Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdarg>
- #include <cstdio>
- #include <cstring>
- #ifdef _MSC_VER
- #pragma warning(disable:4996)
- #endif
- inline static void assert(bool condition,char const* msg) {
- if (!condition) printf("%s",msg);
- }
- inline static void printf_buffer(char const*__restrict format_string, char*__restrict argument_buffer) {
- int num_chars = 0;
- PARSE_CHAR:
- switch (*format_string) {
- case '\0': return;
- case '%': {
- int i = 1;
- char c;
- PARSE_SPECIFIER:
- c = format_string[i++];
- switch (c) {
- case 'd': case 'i':
- case 'u': case 'o': case 'x': case 'X':
- case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': case 'a': case 'A':
- case 'c': case 's': case 'p':
- goto PRINT_SPECIFIER;
- case 'n':
- assert(i==2,"\"%%n\" must contain no intermediary characters!");
- **reinterpret_cast<int**>(argument_buffer) = num_chars;
- argument_buffer += sizeof(int*);
- goto DONE_SPECIFIER;
- case '%':
- assert(i==2,"\"%%%%\" must contain no intermediary characters!");
- putchar('%'); ++num_chars;
- goto DONE_SPECIFIER;
- case '\0': assert(false,"Expected specifier before end of string!");
- default: goto PARSE_SPECIFIER;
- }
- PRINT_SPECIFIER: {
- char* temp = new char[i+1];
- strncpy(temp,format_string,i); temp[i]='\0';
- #define PRINTBRK(TYPE) num_chars+=printf(temp,*reinterpret_cast<TYPE*>(argument_buffer)); argument_buffer+=sizeof(TYPE); break;
- switch (c) {
- case 'd': case 'i': PRINTBRK(int)
- case 'u': case 'o': case 'x': case 'X': PRINTBRK(unsigned int)
- case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': case 'a': case 'A': PRINTBRK(double)
- case 'c': PRINTBRK(char)
- case 's': PRINTBRK(char const*)
- case 'p': PRINTBRK(void*)
- default: assert(false,"Implementation error!");
- }
- #undef PRINTBRK
- delete [] temp;
- }
- DONE_SPECIFIER:
- format_string += i;
- break;
- }
- default:
- putchar(*format_string); ++format_string; ++num_chars;
- break;
- }
- goto PARSE_CHAR;
- }
- template <typename type> inline static void insert(char buffer[], size_t* i, type value) {
- memcpy(buffer+*i,&value, sizeof(type));
- *i += sizeof(type);
- }
- int main(int /*argc*/, char* /*argv*/[]) {
- char buffer[512];
- size_t i = 0;
- int num_chars;
- insert<double>(buffer,&i, 3.14);
- insert<double>(buffer,&i, 3.14f); //Note: when calling a variadic function; floats get promoted to doubles! So, be sure we pass in a double.
- insert<int*>(buffer,&i, &num_chars);
- insert<int>(buffer,&i, 12345);
- insert<char const*>(buffer,&i, "Hello world!");
- PrintFormatString("double: %2.4f, float: %+2.4f, getting characters: ->%n, percent: %%, int: %10d, string: \"%s\"\n",buffer);
- printf("Printed %d characters before the marked point:\n",num_chars);
- for (int i=0;i<num_chars;++i) printf(" "); printf("<-");
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement