Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chitalu committed May 29, 2017
1 parent 4afdcd8 commit d868dfd
Show file tree
Hide file tree
Showing 11 changed files with 473 additions and 444 deletions.
6 changes: 0 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,6 @@ SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES
COMPILE_DEFINITIONS "${CPF_PREPROC_DEFS}"
COMPILE_FLAGS "${CPF_BUILD_FLAGS}")

#
# caching need for use in gtest cmake file
#
SET(CPF_BUILD_FLAGS ${CPF_BUILD_FLAGS} CACHE STRING "adopt same compiler flags.")
SET(CPF_PREPROC_DEFS ${CPF_PREPROC_DEFS} CACHE STRING "adopt same preproc defs.")

IF(CPF_BUILD_SAMPLES)

MACRO(SUBDIRLIST result curdir)
Expand Down
34 changes: 11 additions & 23 deletions incl/cprintf/cprintf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,20 @@

#include <cprintf/internal/cpf_hlpr.h>

#if CPF_DBG_CONFIG
#define cprintf_dbg(format_, ...) cprintf_dbg_impl_(format_, ##__VA_ARGS__);
#else
#define cprintf_dbg(format, ...)
#endif

template <typename FormatType, typename... ArgumentTypes>
inline int cprintf(decltype(stdout) file_stream,
FormatType format,
ArgumentTypes... arguments)
template <typename... Types>
inline int cprintf(decltype(stdout) stream, Types... arguments) noexcept
{
using namespace _cprintf_;
static_assert(is_valid_string_type_<FormatType>::value,
"Error: Invalid format string type.");
verify_args_<ArgumentTypes...> verify_args;

const int error_code = dispatch(file_stream, std::forward<FormatType>(format),
std::forward<ArgumentTypes>(arguments)...);

return error_code;
return _cprintf_::dispatch(stream, std::forward<Types>(arguments)...);
}

template <typename FormatType, typename... ArgumentTypes>
inline int cprintf(FormatType format, ArgumentTypes... arguments)
template <typename... Types>
inline int cprintf(Types... arguments) noexcept
{
return cprintf(stdout, std::forward<FormatType>(format),
std::forward<ArgumentTypes>(arguments)...);
return cprintf(stdout, std::forward<Types>(arguments)...);
}

#if CPF_DBG_CONFIG
#define cprintf_dbg(format_, ...) cprintf_dbg_impl_(format_, ##__VA_ARGS__);
#else
#define cprintf_dbg(format, ...)
#endif
7 changes: 3 additions & 4 deletions incl/cprintf/internal/cpf_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
#endif /*#ifdef CPF_WINDOWS_BUILD*/

#include <algorithm>
#include <stdexcept>

#define CPF_ESC_CHAR ('`')

Expand All @@ -69,13 +68,13 @@
*/

// no error
#define CPF_NO_ERR (0)
#define CPF_SUCCESS (0)

// invalid token(s) encountered in format string
#define CPF_TOKEN_ERR (-1)
#define CPF_FORMAT_STRING_TOKEN_ERROR (-1)

// invalid format specifier(s) in format string
#define CPF_FSPEC_ERR (-2)
#define CPF_FORMAT_SPECIFIER_ERROR (-2)

// mismatch between a format specifier and its corresponding argument
#define CPF_ARG_ERR (-3)
Expand Down
90 changes: 43 additions & 47 deletions incl/cprintf/internal/cpf_carg.h
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
#ifndef __CPF_VERIFY_H__
#define __CPF_VERIFY_H__
#pragma once

#include "cprintf/internal/cpf_type.h"
#include <cassert>

namespace _cprintf_
{

/*
format specifier-to-argument correspondence check
i.e "%d" must correspond to an integral, "%p" to a pointer etc.
/*
format specifier-to-argument correspondence check
i.e "%d" must correspond to an integral, "%p" to a pointer etc.
verifies that the format string contains arguments which
match the given % sequence(s) in the correct order.
note that this is only able to test those format specifiers
found in "std_fmt_specs".
verifies that the format string contains arguments which
match the given % sequence(s) in the correct order.
note that this is only able to test those format specifiers
found in "std_fmt_specs".
We perform runtime checks on the validity of arguments when compared to
their corresonding format specifiers.
We perform runtime checks on the validity of arguments when compared to
their corresonding format specifiers.
This is only done in client debug builds.
*/
CPF_API void format_specifier_correspondence_check(unicode_character_string_ptr_t format);
This is only done in client debug builds.
*/
CPF_API void format_specifier_correspondence_check(unicode_character_string_ptr_t format);

template <class T = int, typename... Ts>
void format_specifier_correspondence_check(unicode_character_string_ptr_t format, T&& farg, Ts&&... args)
{
for (; *format; ++format)
template <class T = int, typename... Ts>
void format_specifier_correspondence_check(unicode_character_string_ptr_t format, T&& farg, Ts&&... args)
{
if (*format != '%' || *++format == '%')
continue;
for (; *format; ++format)
{
if (*format != '%' || *++format == '%')
continue;

wchar_t f = *format;
wchar_t f = *format;

switch (f)
{
switch (f)
{
case 'f':
case 'e':
case 'g':
Expand All @@ -57,35 +56,32 @@ void format_specifier_correspondence_check(unicode_character_string_ptr_t format
if (!std::is_integral<T>::value)
throw CPF_ARG_ERR; // expected an[integral] value"
}
}
break;
case 's':
case 'S':
{
if (!is_valid_string_type_<T>::value)
break;
case 's':
case 'S':
{
throw CPF_ARG_ERR; // expected a value of type[c - string, std::string
// or std::wstring]
if (!is_valid_string_type_<T>::value)
{
throw CPF_ARG_ERR; // expected a value of type[c - string, std::string
// or std::wstring]
}
}
}
break;
case 'p':
{
if (!std::is_pointer<T>::value)
break;
case 'p':
{
throw CPF_ARG_ERR; // expected a[pointer] value
if (!std::is_pointer<T>::value)
{
throw CPF_ARG_ERR; // expected a[pointer] value
}
}
}
break;
default:
// Note: we do not cover all edge cases
break;
}

return format_specifier_correspondence_check(++format, std::forward<Ts>(args)...);
}
default:
break; // Note: we do not cover all edge cases
}

}
return format_specifier_correspondence_check(++format, std::forward<Ts>(args)...);
}

}

#endif /*#ifndef __CPF_VERIFY_H__*/
}
15 changes: 11 additions & 4 deletions incl/cprintf/internal/cpf_hlpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ void print_format_string_layout(file_stream_t file_stream,
ArgType0&& arg0,
RemainingArgTypes&&... args)
{
unicode_string_t printed_string_ = printed_string;
// printed string argument-specifier ('%') count
const auto pstr_argc = get_num_format_specifiers_in_string(printed_string);

Expand Down Expand Up @@ -194,7 +195,7 @@ void print_format_string_layout(file_stream_t file_stream,
print_format_string_layout(
file_stream, end_point_comparator, format_string_layout_iterator,
(!more_args_on_iter && !iter_reached_end) ? i_raw_str : printed_string_,
more_args_on_iter, std::forward<Ts>(args)...);
more_args_on_iter, std::forward<RemainingArgTypes>(args)...);
}
else
{
Expand All @@ -208,25 +209,31 @@ void print_format_string_layout(file_stream_t file_stream,
template <typename FormatType, typename... ArgumentTypes>
int dispatch(file_stream_t file_stream, FormatType&& raw_format, ArgumentTypes&&... args)
{
using namespace _cprintf_;

static_assert(is_valid_string_type_<FormatType>::value, "invalid format string type");

_cprintf_::verify_args_<ArgumentTypes...> _;

unicode_string_t format;

try
{
format = ascii_to_unicode_string_conversion(std::forward<T0>(raw_format));
format = ascii_to_unicode_string_conversion(std::forward<FormatType>(raw_format));
}
catch (...)
{
// runtime string conversion error
return CPF_NWCONV_ERR;
}

int error_code = CPF_NO_ERR;
int error_code = CPF_SUCCESS;

try
{

#if CPF_DBG_CONFIG
format_specifier_correspondence_check( std::forward<const wchar_t*>(format.c_str()), std::forward<Ts>(args)...);
format_specifier_correspondence_check( std::forward<unicode_character_string_ptr_t>(format.c_str()), std::forward<ArgumentTypes>(args)...);
#endif

save_stream_state(file_stream);
Expand Down
Loading

0 comments on commit d868dfd

Please sign in to comment.