From 240041806792fd715799c0ef12e5104794591859 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 1 Aug 2019 11:15:39 -0400 Subject: [PATCH] style --- armsrc/Standalone/hf_colin.c | 99 +- armsrc/frozen.c | 2052 +++++++++++++++++----------------- armsrc/frozen.h | 48 +- armsrc/iso14443a.c | 68 +- armsrc/nprintf.c | 1247 ++++++++++----------- armsrc/nprintf.h | 16 +- armsrc/string.c | 214 ++-- armsrc/string.h | 4 +- client/cmdhfthinfilm.c | 30 +- client/cmdhftopaz.c | 14 +- fpga/lo_adc.v | 4 +- 11 files changed, 1882 insertions(+), 1914 deletions(-) diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 64c5b35db..76e705afe 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -85,7 +85,8 @@ static const uint8_t is_hex[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; static inline uint64_t hex2i(const char *s) { uint64_t val = 0; @@ -333,41 +334,41 @@ void RunMod() { uint64_t key64; // Defines current key uint8_t *keyBlock; // Where the keys will be held in memory. -/* VIGIK EXPIRED DUMP FOR STUDY -Sector 0 -121C7F730208040001FA33F5CB2D021D -44001049164916491649000000000000 -00000000000000000000000000000000 -A0A1A2A3A4A579678800010203040506 -Sector 1 -0F000000000000000000000000000000 -AA0700002102080000740C110600AF13 -000000000000000001740C1108220000 -314B4947495679678800010203040506 -Sector 2 -24E572B923A3D243B402D60CAB576956 -216D6501FC8618B6C426762511AC2DEE -25BF4CEC3618D0BAB3A6E9210D887746 -314B4947495679678800010203040506 -Sector 3 -0FBC41A5D95398E76A1B2029E8EA9735 -088BA2CE732653D0C1147596AFCF94D7 -77B4D91F0442182273A29DEAF7A2D095 -314B4947495679678800010203040506 -Sector 4 -4CEE715866E508CDBC95C640EC9D1E58 -E800457CF8B079414E1B45DD3E6C9317 -77B4D91F0442182273A29DEAF7A2D095 -314B4947495679678800010203040506 -010203040506 0 -Sector 5-0F -00000000000000000000000000000000 -00000000000000000000000000000000 -00000000000000000000000000000000 -FFFFFFFFFFFFFF078069FFFFFFFFFFFF -KEY A : 1KGIV ; -ACCBITS : 796788[00]+VALUE -*/ + /* VIGIK EXPIRED DUMP FOR STUDY + Sector 0 + 121C7F730208040001FA33F5CB2D021D + 44001049164916491649000000000000 + 00000000000000000000000000000000 + A0A1A2A3A4A579678800010203040506 + Sector 1 + 0F000000000000000000000000000000 + AA0700002102080000740C110600AF13 + 000000000000000001740C1108220000 + 314B4947495679678800010203040506 + Sector 2 + 24E572B923A3D243B402D60CAB576956 + 216D6501FC8618B6C426762511AC2DEE + 25BF4CEC3618D0BAB3A6E9210D887746 + 314B4947495679678800010203040506 + Sector 3 + 0FBC41A5D95398E76A1B2029E8EA9735 + 088BA2CE732653D0C1147596AFCF94D7 + 77B4D91F0442182273A29DEAF7A2D095 + 314B4947495679678800010203040506 + Sector 4 + 4CEE715866E508CDBC95C640EC9D1E58 + E800457CF8B079414E1B45DD3E6C9317 + 77B4D91F0442182273A29DEAF7A2D095 + 314B4947495679678800010203040506 + 010203040506 0 + Sector 5-0F + 00000000000000000000000000000000 + 00000000000000000000000000000000 + 00000000000000000000000000000000 + FFFFFFFFFFFFFF078069FFFFFFFFFFFF + KEY A : 1KGIV ; + ACCBITS : 796788[00]+VALUE + */ //---------------------------- // Set of keys to be used. @@ -702,18 +703,18 @@ readysim: uint16_t flags; switch (p_card.uidlen) { - case 10: - flags = FLAG_10B_UID_IN_DATA; - break; - case 7: - flags = FLAG_7B_UID_IN_DATA; - break; - case 4: - flags = FLAG_4B_UID_IN_DATA; - break; - default: - flags = FLAG_UID_IN_EMUL; - break; + case 10: + flags = FLAG_10B_UID_IN_DATA; + break; + case 7: + flags = FLAG_7B_UID_IN_DATA; + break; + case 4: + flags = FLAG_4B_UID_IN_DATA; + break; + default: + flags = FLAG_UID_IN_EMUL; + break; } // Use UID, SAK, ATQA from EMUL, if uid not defined @@ -1031,7 +1032,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data } if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || - (receivedAnswer[0] != 0x0a)) { + (receivedAnswer[0] != 0x0a)) { DbprintfEx(FLAG_NEWLINE, "write block send command error"); break; }; diff --git a/armsrc/frozen.c b/armsrc/frozen.c index f467f9554..5af6faad8 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -29,7 +29,7 @@ #include "BigBuf.h" #define malloc(X) BigBuf_malloc(X) -#define free(X) +#define free(X) #if !defined(WEAK) #if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32) @@ -78,22 +78,22 @@ typedef unsigned _int64 uint64_t; #endif struct frozen { - const char *end; - const char *cur; + const char *end; + const char *cur; - const char *cur_name; - size_t cur_name_len; + const char *cur_name; + size_t cur_name_len; - /* For callback API */ - char path[JSON_MAX_PATH_LEN]; - size_t path_len; - void *callback_data; - json_walk_callback_t callback; + /* For callback API */ + char path[JSON_MAX_PATH_LEN]; + size_t path_len; + void *callback_data; + json_walk_callback_t callback; }; struct fstate { - const char *ptr; - size_t path_len; + const char *ptr; + size_t path_len; }; #define SET_STATE(fr, ptr, str, len) \ @@ -117,18 +117,18 @@ struct fstate { } while (0) static int json_append_to_path(struct frozen *f, const char *str, int size) { - int n = f->path_len; - int left = sizeof(f->path) - n - 1; - if (size > left) size = left; - memcpy(f->path + n, str, size); - f->path[n + size] = '\0'; - f->path_len += size; - return n; + int n = f->path_len; + int left = sizeof(f->path) - n - 1; + if (size > left) size = left; + memcpy(f->path + n, str, size); + f->path[n + size] = '\0'; + f->path_len += size; + return n; } static void json_truncate_path(struct frozen *f, size_t len) { - f->path_len = len; - f->path[len] = '\0'; + f->path_len = len; + f->path[len] = '\0'; } static int json_parse_object(struct frozen *f); @@ -148,660 +148,660 @@ static int json_parse_value(struct frozen *f); #define END_OF_STRING (-1) static int json_left(const struct frozen *f) { - return f->end - f->cur; + return f->end - f->cur; } static int json_isspace(int ch) { - return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; + return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } static void json_skip_whitespaces(struct frozen *f) { - while (f->cur < f->end && json_isspace(*f->cur)) f->cur++; + while (f->cur < f->end && json_isspace(*f->cur)) f->cur++; } static int json_cur(struct frozen *f) { - json_skip_whitespaces(f); - return f->cur >= f->end ? END_OF_STRING : *(unsigned char *) f->cur; + json_skip_whitespaces(f); + return f->cur >= f->end ? END_OF_STRING : *(unsigned char *) f->cur; } static int json_test_and_skip(struct frozen *f, int expected) { - int ch = json_cur(f); - if (ch == expected) { - f->cur++; - return 0; - } - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + int ch = json_cur(f); + if (ch == expected) { + f->cur++; + return 0; + } + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; } static int json_isalpha(int ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } static int json_isdigit(int ch) { - return ch >= '0' && ch <= '9'; + return ch >= '0' && ch <= '9'; } static int json_isxdigit(int ch) { - return json_isdigit(ch) || (ch >= 'a' && ch <= 'f') || - (ch >= 'A' && ch <= 'F'); + return json_isdigit(ch) || (ch >= 'a' && ch <= 'f') || + (ch >= 'A' && ch <= 'F'); } static int json_get_escape_len(const char *s, int len) { - switch (*s) { - case 'u': - return len < 6 ? JSON_STRING_INCOMPLETE - : json_isxdigit(s[1]) && json_isxdigit(s[2]) && - json_isxdigit(s[3]) && json_isxdigit(s[4]) - ? 5 - : JSON_STRING_INVALID; - case '"': - case '\\': - case '/': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - return len < 2 ? JSON_STRING_INCOMPLETE : 1; - default: - return JSON_STRING_INVALID; - } + switch (*s) { + case 'u': + return len < 6 ? JSON_STRING_INCOMPLETE + : json_isxdigit(s[1]) && json_isxdigit(s[2]) && + json_isxdigit(s[3]) && json_isxdigit(s[4]) + ? 5 + : JSON_STRING_INVALID; + case '"': + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + return len < 2 ? JSON_STRING_INCOMPLETE : 1; + default: + return JSON_STRING_INVALID; + } } /* identifier = letter { letter | digit | '_' } */ static int json_parse_identifier(struct frozen *f) { - EXPECT(json_isalpha(json_cur(f)), JSON_STRING_INVALID); - { - SET_STATE(f, f->cur, "", 0); - while (f->cur < f->end && - (*f->cur == '_' || json_isalpha(*f->cur) || json_isdigit(*f->cur))) { - f->cur++; + EXPECT(json_isalpha(json_cur(f)), JSON_STRING_INVALID); + { + SET_STATE(f, f->cur, "", 0); + while (f->cur < f->end && + (*f->cur == '_' || json_isalpha(*f->cur) || json_isdigit(*f->cur))) { + f->cur++; + } + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); } - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); - } - return 0; + return 0; } static int json_get_utf8_char_len(unsigned char ch) { - if ((ch & 0x80) == 0) return 1; - switch (ch & 0xf0) { - case 0xf0: - return 4; - case 0xe0: - return 3; - default: - return 2; - } + if ((ch & 0x80) == 0) return 1; + switch (ch & 0xf0) { + case 0xf0: + return 4; + case 0xe0: + return 3; + default: + return 2; + } } /* string = '"' { quoted_printable_chars } '"' */ static int json_parse_string(struct frozen *f) { - int n, ch = 0, len = 0; - TRY(json_test_and_skip(f, '"')); - { - SET_STATE(f, f->cur, "", 0); - for (; f->cur < f->end; f->cur += len) { - ch = *(unsigned char *) f->cur; - len = json_get_utf8_char_len((unsigned char) ch); - EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ - EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); - if (ch == '\\') { - EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); - len += n; - } else if (ch == '"') { - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); - f->cur++; - break; - }; + int n, ch = 0, len = 0; + TRY(json_test_and_skip(f, '"')); + { + SET_STATE(f, f->cur, "", 0); + for (; f->cur < f->end; f->cur += len) { + ch = *(unsigned char *) f->cur; + len = json_get_utf8_char_len((unsigned char) ch); + EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ + EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); + if (ch == '\\') { + EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); + len += n; + } else if (ch == '"') { + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_STRING, fstate.ptr, f->cur - fstate.ptr); + f->cur++; + break; + }; + } } - } - return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; + return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; } /* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */ static int json_parse_number(struct frozen *f) { - int ch = json_cur(f); - SET_STATE(f, f->cur, "", 0); - if (ch == '-') f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') { - f->cur += 2; + int ch = json_cur(f); + SET_STATE(f, f->cur, "", 0); + if (ch == '-') f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; - } else { - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; - if (f->cur < f->end && f->cur[0] == '.') { - f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + if (f->cur + 1 < f->end && f->cur[0] == '0' && f->cur[1] == 'x') { + f->cur += 2; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; + } else { + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + if (f->cur < f->end && f->cur[0] == '.') { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } + if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { + f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; + EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); + EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); + while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; + } } - if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { - f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; - EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); - EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); - while (f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; - } - } - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); - return 0; + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); + return 0; } #if JSON_ENABLE_ARRAY /* array = '[' [ value { ',' value } ] ']' */ static int json_parse_array(struct frozen *f) { - int i = 0, current_path_len; - char buf[20]; - CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); - TRY(json_test_and_skip(f, '[')); - { + int i = 0, current_path_len; + char buf[20]; + CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); + TRY(json_test_and_skip(f, '[')); { - SET_STATE(f, f->cur - 1, "", 0); - while (json_cur(f) != ']') { - snprintf(buf, sizeof(buf), "[%d]", i); - i++; - current_path_len = json_append_to_path(f, buf, strlen(buf)); - f->cur_name = - f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; - f->cur_name_len = strlen(buf) - 2 /*braces*/; - TRY(json_parse_value(f)); - json_truncate_path(f, current_path_len); - if (json_cur(f) == ',') f->cur++; - } - TRY(json_test_and_skip(f, ']')); - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); + { + SET_STATE(f, f->cur - 1, "", 0); + while (json_cur(f) != ']') { + snprintf(buf, sizeof(buf), "[%d]", i); + i++; + current_path_len = json_append_to_path(f, buf, strlen(buf)); + f->cur_name = + f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; + f->cur_name_len = strlen(buf) - 2 /*braces*/; + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, ']')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_ARRAY_END, fstate.ptr, f->cur - fstate.ptr); + } } - } - return 0; + return 0; } #endif /* JSON_ENABLE_ARRAY */ static int json_expect(struct frozen *f, const char *s, int len, enum json_token_type tok_type) { - int i, n = json_left(f); - SET_STATE(f, f->cur, "", 0); - for (i = 0; i < len; i++) { - if (i >= n) return JSON_STRING_INCOMPLETE; - if (f->cur[i] != s[i]) return JSON_STRING_INVALID; - } - f->cur += len; - json_truncate_path(f, fstate.path_len); + int i, n = json_left(f); + SET_STATE(f, f->cur, "", 0); + for (i = 0; i < len; i++) { + if (i >= n) return JSON_STRING_INCOMPLETE; + if (f->cur[i] != s[i]) return JSON_STRING_INVALID; + } + f->cur += len; + json_truncate_path(f, fstate.path_len); - CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); + CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); - return 0; + return 0; } /* value = 'null' | 'true' | 'false' | number | string | array | object */ static int json_parse_value(struct frozen *f) { - int ch = json_cur(f); + int ch = json_cur(f); - switch (ch) { - case '"': - TRY(json_parse_string(f)); - break; - case '{': - TRY(json_parse_object(f)); - break; + switch (ch) { + case '"': + TRY(json_parse_string(f)); + break; + case '{': + TRY(json_parse_object(f)); + break; #if JSON_ENABLE_ARRAY - case '[': - TRY(json_parse_array(f)); - break; + case '[': + TRY(json_parse_array(f)); + break; #endif - case 'n': - TRY(json_expect(f, "null", 4, JSON_TYPE_NULL)); - break; - case 't': - TRY(json_expect(f, "true", 4, JSON_TYPE_TRUE)); - break; - case 'f': - TRY(json_expect(f, "false", 5, JSON_TYPE_FALSE)); - break; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - TRY(json_parse_number(f)); - break; - default: - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; - } + case 'n': + TRY(json_expect(f, "null", 4, JSON_TYPE_NULL)); + break; + case 't': + TRY(json_expect(f, "true", 4, JSON_TYPE_TRUE)); + break; + case 'f': + TRY(json_expect(f, "false", 5, JSON_TYPE_FALSE)); + break; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + TRY(json_parse_number(f)); + break; + default: + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } - return 0; + return 0; } /* key = identifier | string */ static int json_parse_key(struct frozen *f) { - int ch = json_cur(f); - if (json_isalpha(ch)) { - TRY(json_parse_identifier(f)); - } else if (ch == '"') { - TRY(json_parse_string(f)); - } else { - return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; - } - return 0; + int ch = json_cur(f); + if (json_isalpha(ch)) { + TRY(json_parse_identifier(f)); + } else if (ch == '"') { + TRY(json_parse_string(f)); + } else { + return ch == END_OF_STRING ? JSON_STRING_INCOMPLETE : JSON_STRING_INVALID; + } + return 0; } /* pair = key ':' value */ static int json_parse_pair(struct frozen *f) { - int current_path_len; - const char *tok; - json_skip_whitespaces(f); - tok = f->cur; - TRY(json_parse_key(f)); - { - f->cur_name = *tok == '"' ? tok + 1 : tok; - f->cur_name_len = *tok == '"' ? f->cur - tok - 2 : f->cur - tok; - current_path_len = json_append_to_path(f, f->cur_name, f->cur_name_len); - } - TRY(json_test_and_skip(f, ':')); - TRY(json_parse_value(f)); - json_truncate_path(f, current_path_len); - return 0; + int current_path_len; + const char *tok; + json_skip_whitespaces(f); + tok = f->cur; + TRY(json_parse_key(f)); + { + f->cur_name = *tok == '"' ? tok + 1 : tok; + f->cur_name_len = *tok == '"' ? f->cur - tok - 2 : f->cur - tok; + current_path_len = json_append_to_path(f, f->cur_name, f->cur_name_len); + } + TRY(json_test_and_skip(f, ':')); + TRY(json_parse_value(f)); + json_truncate_path(f, current_path_len); + return 0; } /* object = '{' pair { ',' pair } '}' */ static int json_parse_object(struct frozen *f) { - CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); - TRY(json_test_and_skip(f, '{')); - { - SET_STATE(f, f->cur - 1, ".", 1); - while (json_cur(f) != '}') { - TRY(json_parse_pair(f)); - if (json_cur(f) == ',') f->cur++; + CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); + TRY(json_test_and_skip(f, '{')); + { + SET_STATE(f, f->cur - 1, ".", 1); + while (json_cur(f) != '}') { + TRY(json_parse_pair(f)); + if (json_cur(f) == ',') f->cur++; + } + TRY(json_test_and_skip(f, '}')); + json_truncate_path(f, fstate.path_len); + CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); } - TRY(json_test_and_skip(f, '}')); - json_truncate_path(f, fstate.path_len); - CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); - } - return 0; + return 0; } static int json_doit(struct frozen *f) { - if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID; - if (f->end == f->cur) return JSON_STRING_INCOMPLETE; - return json_parse_value(f); + if (f->cur == 0 || f->end < f->cur) return JSON_STRING_INVALID; + if (f->end == f->cur) return JSON_STRING_INCOMPLETE; + return json_parse_value(f); } int json_escape(struct json_out *out, const char *p, size_t len) WEAK; int json_escape(struct json_out *out, const char *p, size_t len) { - size_t i, cl, n = 0; - const char *hex_digits = "0123456789abcdef"; - const char *specials = "btnvfr"; + size_t i, cl, n = 0; + const char *hex_digits = "0123456789abcdef"; + const char *specials = "btnvfr"; - for (i = 0; i < len; i++) { - unsigned char ch = ((unsigned char *) p)[i]; - if (ch == '"' || ch == '\\') { - n += out->printer(out, "\\", 1); - n += out->printer(out, p + i, 1); - } else if (ch >= '\b' && ch <= '\r') { - n += out->printer(out, "\\", 1); - n += out->printer(out, &specials[ch - '\b'], 1); - } else if (c_isprint(ch)) { - n += out->printer(out, p + i, 1); - } else if ((cl = json_get_utf8_char_len(ch)) == 1) { - n += out->printer(out, "\\u00", 4); - n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); - n += out->printer(out, &hex_digits[ch % 0xf], 1); - } else { - n += out->printer(out, p + i, cl); - i += cl - 1; + for (i = 0; i < len; i++) { + unsigned char ch = ((unsigned char *) p)[i]; + if (ch == '"' || ch == '\\') { + n += out->printer(out, "\\", 1); + n += out->printer(out, p + i, 1); + } else if (ch >= '\b' && ch <= '\r') { + n += out->printer(out, "\\", 1); + n += out->printer(out, &specials[ch - '\b'], 1); + } else if (c_isprint(ch)) { + n += out->printer(out, p + i, 1); + } else if ((cl = json_get_utf8_char_len(ch)) == 1) { + n += out->printer(out, "\\u00", 4); + n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); + n += out->printer(out, &hex_digits[ch % 0xf], 1); + } else { + n += out->printer(out, p + i, cl); + i += cl - 1; + } } - } - return n; + return n; } int json_printer_buf(struct json_out *out, const char *buf, size_t len) WEAK; int json_printer_buf(struct json_out *out, const char *buf, size_t len) { - size_t avail = out->u.buf.size - out->u.buf.len; - size_t n = len < avail ? len : avail; - memcpy(out->u.buf.buf + out->u.buf.len, buf, n); - out->u.buf.len += n; - if (out->u.buf.size > 0) { - size_t idx = out->u.buf.len; - if (idx >= out->u.buf.size) idx = out->u.buf.size - 1; - out->u.buf.buf[idx] = '\0'; - } - return len; + size_t avail = out->u.buf.size - out->u.buf.len; + size_t n = len < avail ? len : avail; + memcpy(out->u.buf.buf + out->u.buf.len, buf, n); + out->u.buf.len += n; + if (out->u.buf.size > 0) { + size_t idx = out->u.buf.len; + if (idx >= out->u.buf.size) idx = out->u.buf.size - 1; + out->u.buf.buf[idx] = '\0'; + } + return len; } int json_printer_file(struct json_out *out, const char *buf, size_t len) WEAK; int json_printer_file(struct json_out *out, const char *buf, size_t len) { - return fwrite(buf, 1, len, out->u.fp); + return fwrite(buf, 1, len, out->u.fp); } #if JSON_ENABLE_BASE64 static int b64idx(int c) { - if (c < 26) { - return c + 'A'; - } else if (c < 52) { - return c - 26 + 'a'; - } else if (c < 62) { - return c - 52 + '0'; - } else { - return c == 62 ? '+' : '/'; - } + if (c < 26) { + return c + 'A'; + } else if (c < 52) { + return c - 26 + 'a'; + } else if (c < 62) { + return c - 52 + '0'; + } else { + return c == 62 ? '+' : '/'; + } } static int b64rev(int c) { - if (c >= 'A' && c <= 'Z') { - return c - 'A'; - } else if (c >= 'a' && c <= 'z') { - return c + 26 - 'a'; - } else if (c >= '0' && c <= '9') { - return c + 52 - '0'; - } else if (c == '+') { - return 62; - } else if (c == '/') { - return 63; - } else { - return 64; - } + if (c >= 'A' && c <= 'Z') { + return c - 'A'; + } else if (c >= 'a' && c <= 'z') { + return c + 26 - 'a'; + } else if (c >= '0' && c <= '9') { + return c + 52 - '0'; + } else if (c == '+') { + return 62; + } else if (c == '/') { + return 63; + } else { + return 64; + } } static int b64enc(struct json_out *out, const unsigned char *p, int n) { - char buf[4]; - int i, len = 0; - for (i = 0; i < n; i += 3) { - int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0; - buf[0] = b64idx(a >> 2); - buf[1] = b64idx((a & 3) << 4 | (b >> 4)); - buf[2] = b64idx((b & 15) << 2 | (c >> 6)); - buf[3] = b64idx(c & 63); - if (i + 1 >= n) buf[2] = '='; - if (i + 2 >= n) buf[3] = '='; - len += out->printer(out, buf, sizeof(buf)); - } - return len; + char buf[4]; + int i, len = 0; + for (i = 0; i < n; i += 3) { + int a = p[i], b = i + 1 < n ? p[i + 1] : 0, c = i + 2 < n ? p[i + 2] : 0; + buf[0] = b64idx(a >> 2); + buf[1] = b64idx((a & 3) << 4 | (b >> 4)); + buf[2] = b64idx((b & 15) << 2 | (c >> 6)); + buf[3] = b64idx(c & 63); + if (i + 1 >= n) buf[2] = '='; + if (i + 2 >= n) buf[3] = '='; + len += out->printer(out, buf, sizeof(buf)); + } + return len; } static int b64dec(const char *src, int n, char *dst) { - const char *end = src + n; - int len = 0; - while (src + 3 < end) { - int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]), - d = b64rev(src[3]); - dst[len++] = (a << 2) | (b >> 4); - if (src[2] != '=') { - dst[len++] = (b << 4) | (c >> 2); - if (src[3] != '=') { - dst[len++] = (c << 6) | d; - } + const char *end = src + n; + int len = 0; + while (src + 3 < end) { + int a = b64rev(src[0]), b = b64rev(src[1]), c = b64rev(src[2]), + d = b64rev(src[3]); + dst[len++] = (a << 2) | (b >> 4); + if (src[2] != '=') { + dst[len++] = (b << 4) | (c >> 2); + if (src[3] != '=') { + dst[len++] = (c << 6) | d; + } + } + src += 4; } - src += 4; - } - return len; + return len; } #endif /* JSON_ENABLE_BASE64 */ static unsigned char hexdec(const char *s) { #define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W') - int a = c_tolower(*(const unsigned char *) s); - int b = c_tolower(*(const unsigned char *) (s + 1)); - return (HEXTOI(a) << 4) | HEXTOI(b); + int a = c_tolower(*(const unsigned char *) s); + int b = c_tolower(*(const unsigned char *)(s + 1)); + return (HEXTOI(a) << 4) | HEXTOI(b); } int json_vprintf(struct json_out *out, const char *fmt, va_list xap) WEAK; int json_vprintf(struct json_out *out, const char *fmt, va_list xap) { - int len = 0; - const char *quote = "\"", *null = "null"; - va_list ap; - va_copy(ap, xap); + int len = 0; + const char *quote = "\"", *null = "null"; + va_list ap; + va_copy(ap, xap); - while (*fmt != '\0') { - if (strchr(":, \r\n\t[]{}\"", *fmt) != NULL) { - len += out->printer(out, fmt, 1); - fmt++; - } else if (fmt[0] == '%') { - char buf[21]; - size_t skip = 2; + while (*fmt != '\0') { + if (strchr(":, \r\n\t[]{}\"", *fmt) != NULL) { + len += out->printer(out, fmt, 1); + fmt++; + } else if (fmt[0] == '%') { + char buf[21]; + size_t skip = 2; - if (fmt[1] == 'l' && fmt[2] == 'l' && (fmt[3] == 'd' || fmt[3] == 'u')) { - int64_t val = va_arg(ap, int64_t); - const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT; - snprintf(buf, sizeof(buf), fmt2, val); - len += out->printer(out, buf, strlen(buf)); - skip += 2; - } else if (fmt[1] == 'z' && fmt[2] == 'u') { - size_t val = va_arg(ap, size_t); - snprintf(buf, sizeof(buf), "%lu", (unsigned long) val); - len += out->printer(out, buf, strlen(buf)); - skip += 1; - } else if (fmt[1] == 'M') { - json_printf_callback_t f = va_arg(ap, json_printf_callback_t); - len += f(out, &ap); - } else if (fmt[1] == 'B') { - int val = va_arg(ap, int); - const char *str = val ? "true" : "false"; - len += out->printer(out, str, strlen(str)); - } else if (fmt[1] == 'H') { + if (fmt[1] == 'l' && fmt[2] == 'l' && (fmt[3] == 'd' || fmt[3] == 'u')) { + int64_t val = va_arg(ap, int64_t); + const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT; + snprintf(buf, sizeof(buf), fmt2, val); + len += out->printer(out, buf, strlen(buf)); + skip += 2; + } else if (fmt[1] == 'z' && fmt[2] == 'u') { + size_t val = va_arg(ap, size_t); + snprintf(buf, sizeof(buf), "%lu", (unsigned long) val); + len += out->printer(out, buf, strlen(buf)); + skip += 1; + } else if (fmt[1] == 'M') { + json_printf_callback_t f = va_arg(ap, json_printf_callback_t); + len += f(out, &ap); + } else if (fmt[1] == 'B') { + int val = va_arg(ap, int); + const char *str = val ? "true" : "false"; + len += out->printer(out, str, strlen(str)); + } else if (fmt[1] == 'H') { #if JSON_ENABLE_HEX - const char *hex = "0123456789abcdef"; - int i, n = va_arg(ap, int); - const unsigned char *p = va_arg(ap, const unsigned char *); - len += out->printer(out, quote, 1); - for (i = 0; i < n; i++) { - len += out->printer(out, &hex[(p[i] >> 4) & 0xf], 1); - len += out->printer(out, &hex[p[i] & 0xf], 1); - } - len += out->printer(out, quote, 1); + const char *hex = "0123456789abcdef"; + int i, n = va_arg(ap, int); + const unsigned char *p = va_arg(ap, const unsigned char *); + len += out->printer(out, quote, 1); + for (i = 0; i < n; i++) { + len += out->printer(out, &hex[(p[i] >> 4) & 0xf], 1); + len += out->printer(out, &hex[p[i] & 0xf], 1); + } + len += out->printer(out, quote, 1); #endif /* JSON_ENABLE_HEX */ - } else if (fmt[1] == 'V') { + } else if (fmt[1] == 'V') { #if JSON_ENABLE_BASE64 - const unsigned char *p = va_arg(ap, const unsigned char *); - int n = va_arg(ap, int); - len += out->printer(out, quote, 1); - len += b64enc(out, p, n); - len += out->printer(out, quote, 1); + const unsigned char *p = va_arg(ap, const unsigned char *); + int n = va_arg(ap, int); + len += out->printer(out, quote, 1); + len += b64enc(out, p, n); + len += out->printer(out, quote, 1); #endif /* JSON_ENABLE_BASE64 */ - } else if (fmt[1] == 'Q' || - (fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 'Q')) { - size_t l = 0; - const char *p; + } else if (fmt[1] == 'Q' || + (fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 'Q')) { + size_t l = 0; + const char *p; - if (fmt[1] == '.') { - l = (size_t) va_arg(ap, int); - skip += 2; - } - p = va_arg(ap, char *); + if (fmt[1] == '.') { + l = (size_t) va_arg(ap, int); + skip += 2; + } + p = va_arg(ap, char *); - if (p == NULL) { - len += out->printer(out, null, 4); + if (p == NULL) { + len += out->printer(out, null, 4); + } else { + if (fmt[1] == 'Q') { + l = strlen(p); + } + len += out->printer(out, quote, 1); + len += json_escape(out, p, l); + len += out->printer(out, quote, 1); + } + } else { + /* + * we delegate printing to the system printf. + * The goal here is to delegate all modifiers parsing to the system + * printf, as you can see below we still have to parse the format + * types. + * + * Currently, %s with strings longer than 20 chars will require + * double-buffering (an auxiliary buffer will be allocated from heap). + * TODO(dfrank): reimplement %s and %.*s in order to avoid that. + */ + + const char *end_of_format_specifier = "sdfFeEgGlhuIcx.*-0123456789"; + int n = strspn(fmt + 1, end_of_format_specifier); + char *pbuf = buf; + int need_len, size = sizeof(buf); + char fmt2[20]; + va_list ap_copy; + strncpy(fmt2, fmt, + n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1); + fmt2[n + 1] = '\0'; + + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + + if (need_len < 0) { + /* + * Windows & eCos vsnprintf implementation return -1 on overflow + * instead of needed size. + */ + pbuf = NULL; + while (need_len < 0) { + free(pbuf); + size *= 2; + if ((pbuf = (char *) malloc(size)) == NULL) break; + va_copy(ap_copy, ap); + need_len = vsnprintf(pbuf, size, fmt2, ap_copy); + va_end(ap_copy); + } + } else if (need_len >= (int) sizeof(buf)) { + /* + * resulting string doesn't fit into a stack-allocated buffer `buf`, + * so we need to allocate a new buffer from heap and use it + */ + if ((pbuf = (char *) malloc(need_len + 1)) != NULL) { + va_copy(ap_copy, ap); + vsnprintf(pbuf, need_len + 1, fmt2, ap_copy); + va_end(ap_copy); + } + } + if (pbuf == NULL) { + buf[0] = '\0'; + pbuf = buf; + } + + /* + * however we need to parse the type ourselves in order to advance + * the va_list by the correct amount; there is no portable way to + * inherit the advancement made by vprintf. + * 32-bit (linux or windows) passes va_list by value. + */ + if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) || + (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) { + (void) va_arg(ap, int64_t); + } else if (strcmp(fmt2, "%.*s") == 0) { + (void) va_arg(ap, int); + (void) va_arg(ap, char *); + } else { + switch (fmt2[n]) { + case 'u': + case 'd': + (void) va_arg(ap, int); + break; + case 'g': + case 'f': + (void) va_arg(ap, double); + break; + case 'p': + (void) va_arg(ap, void *); + break; + default: + /* many types are promoted to int */ + (void) va_arg(ap, int); + } + } + + len += out->printer(out, pbuf, strlen(pbuf)); + skip = n + 1; + + /* If buffer was allocated from heap, free it */ + if (pbuf != buf) { + free(pbuf); + pbuf = NULL; + } + } + fmt += skip; + } else if (*fmt == '_' || json_isalpha(*fmt)) { + len += out->printer(out, quote, 1); + while (*fmt == '_' || json_isalpha(*fmt) || json_isdigit(*fmt)) { + len += out->printer(out, fmt, 1); + fmt++; + } + len += out->printer(out, quote, 1); } else { - if (fmt[1] == 'Q') { - l = strlen(p); - } - len += out->printer(out, quote, 1); - len += json_escape(out, p, l); - len += out->printer(out, quote, 1); + len += out->printer(out, fmt, 1); + fmt++; } - } else { - /* - * we delegate printing to the system printf. - * The goal here is to delegate all modifiers parsing to the system - * printf, as you can see below we still have to parse the format - * types. - * - * Currently, %s with strings longer than 20 chars will require - * double-buffering (an auxiliary buffer will be allocated from heap). - * TODO(dfrank): reimplement %s and %.*s in order to avoid that. - */ - - const char *end_of_format_specifier = "sdfFeEgGlhuIcx.*-0123456789"; - int n = strspn(fmt + 1, end_of_format_specifier); - char *pbuf = buf; - int need_len, size = sizeof(buf); - char fmt2[20]; - va_list ap_copy; - strncpy(fmt2, fmt, - n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1); - fmt2[n + 1] = '\0'; - - va_copy(ap_copy, ap); - need_len = vsnprintf(pbuf, size, fmt2, ap_copy); - va_end(ap_copy); - - if (need_len < 0) { - /* - * Windows & eCos vsnprintf implementation return -1 on overflow - * instead of needed size. - */ - pbuf = NULL; - while (need_len < 0) { - free(pbuf); - size *= 2; - if ((pbuf = (char *) malloc(size)) == NULL) break; - va_copy(ap_copy, ap); - need_len = vsnprintf(pbuf, size, fmt2, ap_copy); - va_end(ap_copy); - } - } else if (need_len >= (int) sizeof(buf)) { - /* - * resulting string doesn't fit into a stack-allocated buffer `buf`, - * so we need to allocate a new buffer from heap and use it - */ - if ((pbuf = (char *) malloc(need_len + 1)) != NULL) { - va_copy(ap_copy, ap); - vsnprintf(pbuf, need_len + 1, fmt2, ap_copy); - va_end(ap_copy); - } - } - if (pbuf == NULL) { - buf[0] = '\0'; - pbuf = buf; - } - - /* - * however we need to parse the type ourselves in order to advance - * the va_list by the correct amount; there is no portable way to - * inherit the advancement made by vprintf. - * 32-bit (linux or windows) passes va_list by value. - */ - if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) || - (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) { - (void) va_arg(ap, int64_t); - } else if (strcmp(fmt2, "%.*s") == 0) { - (void) va_arg(ap, int); - (void) va_arg(ap, char *); - } else { - switch (fmt2[n]) { - case 'u': - case 'd': - (void) va_arg(ap, int); - break; - case 'g': - case 'f': - (void) va_arg(ap, double); - break; - case 'p': - (void) va_arg(ap, void *); - break; - default: - /* many types are promoted to int */ - (void) va_arg(ap, int); - } - } - - len += out->printer(out, pbuf, strlen(pbuf)); - skip = n + 1; - - /* If buffer was allocated from heap, free it */ - if (pbuf != buf) { - free(pbuf); - pbuf = NULL; - } - } - fmt += skip; - } else if (*fmt == '_' || json_isalpha(*fmt)) { - len += out->printer(out, quote, 1); - while (*fmt == '_' || json_isalpha(*fmt) || json_isdigit(*fmt)) { - len += out->printer(out, fmt, 1); - fmt++; - } - len += out->printer(out, quote, 1); - } else { - len += out->printer(out, fmt, 1); - fmt++; } - } - va_end(ap); + va_end(ap); - return len; + return len; } int json_printf(struct json_out *out, const char *fmt, ...) WEAK; int json_printf(struct json_out *out, const char *fmt, ...) { - int n; - va_list ap; - va_start(ap, fmt); - n = json_vprintf(out, fmt, ap); - va_end(ap); - return n; + int n; + va_list ap; + va_start(ap, fmt); + n = json_vprintf(out, fmt, ap); + va_end(ap); + return n; } int json_printf_array(struct json_out *out, va_list *ap) WEAK; int json_printf_array(struct json_out *out, va_list *ap) { - int len = 0; - char *arr = va_arg(*ap, char *); - size_t i, arr_size = va_arg(*ap, size_t); - size_t elem_size = va_arg(*ap, size_t); - const char *fmt = va_arg(*ap, char *); - len += json_printf(out, "[", 1); - for (i = 0; arr != NULL && i < arr_size / elem_size; i++) { - union { - int64_t i; - double d; - } val; - memcpy(&val, arr + i * elem_size, - elem_size > sizeof(val) ? sizeof(val) : elem_size); - if (i > 0) len += json_printf(out, ", "); - if (strpbrk(fmt, "efg") != NULL) { - len += json_printf(out, fmt, val.d); - } else { - len += json_printf(out, fmt, val.i); + int len = 0; + char *arr = va_arg(*ap, char *); + size_t i, arr_size = va_arg(*ap, size_t); + size_t elem_size = va_arg(*ap, size_t); + const char *fmt = va_arg(*ap, char *); + len += json_printf(out, "[", 1); + for (i = 0; arr != NULL && i < arr_size / elem_size; i++) { + union { + int64_t i; + double d; + } val; + memcpy(&val, arr + i * elem_size, + elem_size > sizeof(val) ? sizeof(val) : elem_size); + if (i > 0) len += json_printf(out, ", "); + if (strpbrk(fmt, "efg") != NULL) { + len += json_printf(out, fmt, val.d); + } else { + len += json_printf(out, fmt, val.i); + } } - } - len += json_printf(out, "]", 1); - return len; + len += json_printf(out, "]", 1); + return len; } #ifdef _WIN32 int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) WEAK; int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap) { - int res = _vsnprintf(str, size, format, ap); - va_end(ap); - if (res >= size) { - str[size - 1] = '\0'; - } - return res; + int res = _vsnprintf(str, size, format, ap); + va_end(ap); + if (res >= size) { + str[size - 1] = '\0'; + } + return res; } int cs_win_snprintf(char *str, size_t size, const char *format, ...) WEAK; int cs_win_snprintf(char *str, size_t size, const char *format, ...) { - int res; - va_list ap; - va_start(ap, format); - res = vsnprintf(str, size, format, ap); - va_end(ap); - return res; + int res; + va_list ap; + va_start(ap, format); + res = vsnprintf(str, size, format, ap); + va_end(ap); + return res; } #endif /* _WIN32 */ @@ -809,665 +809,665 @@ int json_walk(const char *json_string, int json_string_length, json_walk_callback_t callback, void *callback_data) WEAK; int json_walk(const char *json_string, int json_string_length, json_walk_callback_t callback, void *callback_data) { - struct frozen frozen; + struct frozen frozen; - memset(&frozen, 0, sizeof(frozen)); - frozen.end = json_string + json_string_length; - frozen.cur = json_string; - frozen.callback_data = callback_data; - frozen.callback = callback; + memset(&frozen, 0, sizeof(frozen)); + frozen.end = json_string + json_string_length; + frozen.cur = json_string; + frozen.callback_data = callback_data; + frozen.callback = callback; - TRY(json_doit(&frozen)); + TRY(json_doit(&frozen)); - return frozen.cur - json_string; + return frozen.cur - json_string; } struct scan_array_info { - int found; - char path[JSON_MAX_PATH_LEN]; - struct json_token *token; + int found; + char path[JSON_MAX_PATH_LEN]; + struct json_token *token; }; static void json_scanf_array_elem_cb(void *callback_data, const char *name, size_t name_len, const char *path, const struct json_token *token) { - struct scan_array_info *info = (struct scan_array_info *) callback_data; + struct scan_array_info *info = (struct scan_array_info *) callback_data; - (void) name; - (void) name_len; + (void) name; + (void) name_len; - if (strcmp(path, info->path) == 0) { - *info->token = *token; - info->found = 1; - } + if (strcmp(path, info->path) == 0) { + *info->token = *token; + info->found = 1; + } } int json_scanf_array_elem(const char *s, int len, const char *path, int idx, struct json_token *token) WEAK; int json_scanf_array_elem(const char *s, int len, const char *path, int idx, struct json_token *token) { - struct scan_array_info info; - info.token = token; - info.found = 0; - memset(token, 0, sizeof(*token)); - snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx); - json_walk(s, len, json_scanf_array_elem_cb, &info); - return info.found ? token->len : -1; + struct scan_array_info info; + info.token = token; + info.found = 0; + memset(token, 0, sizeof(*token)); + snprintf(info.path, sizeof(info.path), "%s[%d]", path, idx); + json_walk(s, len, json_scanf_array_elem_cb, &info); + return info.found ? token->len : -1; } struct json_scanf_info { - int num_conversions; - char *path; - const char *fmt; - void *target; - void *user_data; - int type; + int num_conversions; + char *path; + const char *fmt; + void *target; + void *user_data; + int type; }; int json_unescape(const char *src, int slen, char *dst, int dlen) WEAK; int json_unescape(const char *src, int slen, char *dst, int dlen) { - char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p; - const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t"; + char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p; + const char *esc1 = "\"\\/bfnrt", *esc2 = "\"\\/\b\f\n\r\t"; - while (src < send) { - if (*src == '\\') { - if (++src >= send) return JSON_STRING_INCOMPLETE; - if (*src == 'u') { - if (send - src < 5) return JSON_STRING_INCOMPLETE; - /* Here we go: this is a \u.... escape. Process simple one-byte chars */ - if (src[1] == '0' && src[2] == '0') { - /* This is \u00xx character from the ASCII range */ - if (dst < dend) *dst = hexdec(src + 3); - src += 4; + while (src < send) { + if (*src == '\\') { + if (++src >= send) return JSON_STRING_INCOMPLETE; + if (*src == 'u') { + if (send - src < 5) return JSON_STRING_INCOMPLETE; + /* Here we go: this is a \u.... escape. Process simple one-byte chars */ + if (src[1] == '0' && src[2] == '0') { + /* This is \u00xx character from the ASCII range */ + if (dst < dend) *dst = hexdec(src + 3); + src += 4; + } else { + /* Complex \uXXXX escapes drag utf8 lib... Do it at some stage */ + return JSON_STRING_INVALID; + } + } else if ((p = (char *) strchr(esc1, *src)) != NULL) { + if (dst < dend) *dst = esc2[p - esc1]; + } else { + return JSON_STRING_INVALID; + } } else { - /* Complex \uXXXX escapes drag utf8 lib... Do it at some stage */ - return JSON_STRING_INVALID; + if (dst < dend) *dst = *src; } - } else if ((p = (char *) strchr(esc1, *src)) != NULL) { - if (dst < dend) *dst = esc2[p - esc1]; - } else { - return JSON_STRING_INVALID; - } - } else { - if (dst < dend) *dst = *src; + dst++; + src++; } - dst++; - src++; - } - return dst - orig_dst; + return dst - orig_dst; } static void json_scanf_cb(void *callback_data, const char *name, size_t name_len, const char *path, const struct json_token *token) { - struct json_scanf_info *info = (struct json_scanf_info *) callback_data; - char buf[32]; /* Must be enough to hold numbers */ + struct json_scanf_info *info = (struct json_scanf_info *) callback_data; + char buf[32]; /* Must be enough to hold numbers */ - (void) name; - (void) name_len; + (void) name; + (void) name_len; - if (token->ptr == NULL) { - /* - * We're not interested here in the events for which we have no value; - * namely, JSON_TYPE_OBJECT_START and JSON_TYPE_ARRAY_START - */ - return; - } - - if (strcmp(path, info->path) != 0) { - /* It's not the path we're looking for, so, just ignore this callback */ - return; - } - - switch (info->type) { - case 'B': - info->num_conversions++; - switch (sizeof(bool)) { - case sizeof(char): - *(char *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); - break; - case sizeof(int): - *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); - break; - default: - /* should never be here */ - abort(); - } - break; - case 'M': { - union { - void *p; - json_scanner_t f; - } u = {info->target}; - info->num_conversions++; - u.f(token->ptr, token->len, info->user_data); - break; + if (token->ptr == NULL) { + /* + * We're not interested here in the events for which we have no value; + * namely, JSON_TYPE_OBJECT_START and JSON_TYPE_ARRAY_START + */ + return; } - case 'Q': { - char **dst = (char **) info->target; - if (token->type == JSON_TYPE_NULL) { - *dst = NULL; - } else { - int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0); - if (unescaped_len >= 0 && - (*dst = (char *) malloc(unescaped_len + 1)) != NULL) { - info->num_conversions++; - if (json_unescape(token->ptr, token->len, *dst, unescaped_len) == - unescaped_len) { - (*dst)[unescaped_len] = '\0'; - } else { - free(*dst); - *dst = NULL; - } + + if (strcmp(path, info->path) != 0) { + /* It's not the path we're looking for, so, just ignore this callback */ + return; + } + + switch (info->type) { + case 'B': + info->num_conversions++; + switch (sizeof(bool)) { + case sizeof(char): + *(char *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + case sizeof(int): + *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0); + break; + default: + /* should never be here */ + abort(); + } + break; + case 'M': { + union { + void *p; + json_scanner_t f; + } u = {info->target}; + info->num_conversions++; + u.f(token->ptr, token->len, info->user_data); + break; } - } - break; - } - case 'H': { + case 'Q': { + char **dst = (char **) info->target; + if (token->type == JSON_TYPE_NULL) { + *dst = NULL; + } else { + int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0); + if (unescaped_len >= 0 && + (*dst = (char *) malloc(unescaped_len + 1)) != NULL) { + info->num_conversions++; + if (json_unescape(token->ptr, token->len, *dst, unescaped_len) == + unescaped_len) { + (*dst)[unescaped_len] = '\0'; + } else { + free(*dst); + *dst = NULL; + } + } + } + break; + } + case 'H': { #if JSON_ENABLE_HEX - char **dst = (char **) info->user_data; - int i, len = token->len / 2; - *(int *) info->target = len; - if ((*dst = (char *) malloc(len + 1)) != NULL) { - for (i = 0; i < len; i++) { - (*dst)[i] = hexdec(token->ptr + 2 * i); - } - (*dst)[len] = '\0'; - info->num_conversions++; - } + char **dst = (char **) info->user_data; + int i, len = token->len / 2; + *(int *) info->target = len; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + for (i = 0; i < len; i++) { + (*dst)[i] = hexdec(token->ptr + 2 * i); + } + (*dst)[len] = '\0'; + info->num_conversions++; + } #endif /* JSON_ENABLE_HEX */ - break; - } - case 'V': { + break; + } + case 'V': { #if JSON_ENABLE_BASE64 - char **dst = (char **) info->target; - int len = token->len * 4 / 3 + 2; - if ((*dst = (char *) malloc(len + 1)) != NULL) { - int n = b64dec(token->ptr, token->len, *dst); - (*dst)[n] = '\0'; - *(int *) info->user_data = n; - info->num_conversions++; - } + char **dst = (char **) info->target; + int len = token->len * 4 / 3 + 2; + if ((*dst = (char *) malloc(len + 1)) != NULL) { + int n = b64dec(token->ptr, token->len, *dst); + (*dst)[n] = '\0'; + *(int *) info->user_data = n; + info->num_conversions++; + } #endif /* JSON_ENABLE_BASE64 */ - break; - } - case 'T': - info->num_conversions++; - *(struct json_token *) info->target = *token; - break; - default: - if (token->len >= (int) sizeof(buf)) break; - /* Before converting, copy into tmp buffer in order to 0-terminate it */ - memcpy(buf, token->ptr, token->len); - buf[token->len] = '\0'; - /* NB: Use of base 0 for %d, %ld, %u and %lu is intentional. */ - if (info->fmt[1] == 'd' || (info->fmt[1] == 'l' && info->fmt[2] == 'd') || - info->fmt[1] == 'i') { - char *endptr = NULL; - long r = strtol(buf, &endptr, 0 /* base */); - if (*endptr == '\0') { - if (info->fmt[1] == 'l') { - *((long *) info->target) = r; - } else { - *((int *) info->target) = (int) r; - } - info->num_conversions++; + break; } - } else if (info->fmt[1] == 'u' || - (info->fmt[1] == 'l' && info->fmt[2] == 'u')) { - char *endptr = NULL; - unsigned long r = strtoul(buf, &endptr, 0 /* base */); - if (*endptr == '\0') { - if (info->fmt[1] == 'l') { - *((unsigned long *) info->target) = r; - } else { - *((unsigned int *) info->target) = (unsigned int) r; - } - info->num_conversions++; - } - } else { + case 'T': + info->num_conversions++; + *(struct json_token *) info->target = *token; + break; + default: + if (token->len >= (int) sizeof(buf)) break; + /* Before converting, copy into tmp buffer in order to 0-terminate it */ + memcpy(buf, token->ptr, token->len); + buf[token->len] = '\0'; + /* NB: Use of base 0 for %d, %ld, %u and %lu is intentional. */ + if (info->fmt[1] == 'd' || (info->fmt[1] == 'l' && info->fmt[2] == 'd') || + info->fmt[1] == 'i') { + char *endptr = NULL; + long r = strtol(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((long *) info->target) = r; + } else { + *((int *) info->target) = (int) r; + } + info->num_conversions++; + } + } else if (info->fmt[1] == 'u' || + (info->fmt[1] == 'l' && info->fmt[2] == 'u')) { + char *endptr = NULL; + unsigned long r = strtoul(buf, &endptr, 0 /* base */); + if (*endptr == '\0') { + if (info->fmt[1] == 'l') { + *((unsigned long *) info->target) = r; + } else { + *((unsigned int *) info->target) = (unsigned int) r; + } + info->num_conversions++; + } + } else { #if !JSON_MINIMAL - info->num_conversions += sscanf(buf, info->fmt, info->target); + info->num_conversions += sscanf(buf, info->fmt, info->target); #endif - } - break; - } + } + break; + } } int json_vscanf(const char *s, int len, const char *fmt, va_list ap) WEAK; int json_vscanf(const char *s, int len, const char *fmt, va_list ap) { - char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; - int i = 0; - char *p = NULL; - struct json_scanf_info info = {0, path, fmtbuf, NULL, NULL, 0}; + char path[JSON_MAX_PATH_LEN] = "", fmtbuf[20]; + int i = 0; + char *p = NULL; + struct json_scanf_info info = {0, path, fmtbuf, NULL, NULL, 0}; - while (fmt[i] != '\0') { - if (fmt[i] == '{') { - strcat(path, "."); - i++; - } else if (fmt[i] == '}') { - if ((p = strrchr(path, '.')) != NULL) *p = '\0'; - i++; - } else if (fmt[i] == '%') { - info.target = va_arg(ap, void *); - info.type = fmt[i + 1]; - switch (fmt[i + 1]) { - case 'M': - case 'V': - case 'H': - info.user_data = va_arg(ap, void *); - /* FALLTHROUGH */ - case 'B': - case 'Q': - case 'T': - i += 2; - break; - default: { - const char *delims = ", \t\r\n]}"; - int conv_len = strcspn(fmt + i + 1, delims) + 1; - memcpy(fmtbuf, fmt + i, conv_len); - fmtbuf[conv_len] = '\0'; - i += conv_len; - i += strspn(fmt + i, delims); - break; + while (fmt[i] != '\0') { + if (fmt[i] == '{') { + strcat(path, "."); + i++; + } else if (fmt[i] == '}') { + if ((p = strrchr(path, '.')) != NULL) * p = '\0'; + i++; + } else if (fmt[i] == '%') { + info.target = va_arg(ap, void *); + info.type = fmt[i + 1]; + switch (fmt[i + 1]) { + case 'M': + case 'V': + case 'H': + info.user_data = va_arg(ap, void *); + /* FALLTHROUGH */ + case 'B': + case 'Q': + case 'T': + i += 2; + break; + default: { + const char *delims = ", \t\r\n]}"; + int conv_len = strcspn(fmt + i + 1, delims) + 1; + memcpy(fmtbuf, fmt + i, conv_len); + fmtbuf[conv_len] = '\0'; + i += conv_len; + i += strspn(fmt + i, delims); + break; + } + } + json_walk(s, len, json_scanf_cb, &info); + } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { + char *pe; + const char *delims = ": \r\n\t"; + int key_len = strcspn(&fmt[i], delims); + if ((p = strrchr(path, '.')) != NULL) p[1] = '\0'; + pe = path + strlen(path); + memcpy(pe, fmt + i, key_len); + pe[key_len] = '\0'; + i += key_len + strspn(fmt + i + key_len, delims); + } else { + i++; } - } - json_walk(s, len, json_scanf_cb, &info); - } else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1) { - char *pe; - const char *delims = ": \r\n\t"; - int key_len = strcspn(&fmt[i], delims); - if ((p = strrchr(path, '.')) != NULL) p[1] = '\0'; - pe = path + strlen(path); - memcpy(pe, fmt + i, key_len); - pe[key_len] = '\0'; - i += key_len + strspn(fmt + i + key_len, delims); - } else { - i++; } - } - return info.num_conversions; + return info.num_conversions; } int json_scanf(const char *str, int len, const char *fmt, ...) WEAK; int json_scanf(const char *str, int len, const char *fmt, ...) { - int result; - va_list ap; - va_start(ap, fmt); - result = json_vscanf(str, len, fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, fmt); + result = json_vscanf(str, len, fmt, ap); + va_end(ap); + return result; } int json_vfprintf(const char *file_name, const char *fmt, va_list ap) WEAK; int json_vfprintf(const char *file_name, const char *fmt, va_list ap) { - int res = -1; - FILE *fp = fopen(file_name, "wb"); - if (fp != NULL) { - struct json_out out = JSON_OUT_FILE(fp); - res = json_vprintf(&out, fmt, ap); - fputc('\n', fp); - fclose(fp); - } - return res; + int res = -1; + FILE *fp = fopen(file_name, "wb"); + if (fp != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_vprintf(&out, fmt, ap); + fputc('\n', fp); + fclose(fp); + } + return res; } int json_fprintf(const char *file_name, const char *fmt, ...) WEAK; int json_fprintf(const char *file_name, const char *fmt, ...) { - int result; - va_list ap; - va_start(ap, fmt); - result = json_vfprintf(file_name, fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, fmt); + result = json_vfprintf(file_name, fmt, ap); + va_end(ap); + return result; } char *json_fread(const char *path) WEAK; char *json_fread(const char *path) { - FILE *fp; - char *data = NULL; - if ((fp = fopen(path, "rb")) == NULL) { - } else if (fseek(fp, 0, SEEK_END) != 0) { - fclose(fp); - } else { - long size = ftell(fp); - if (size > 0 && (data = (char *) malloc(size + 1)) != NULL) { - fseek(fp, 0, SEEK_SET); /* Some platforms might not have rewind(), Oo */ - if (fread(data, 1, size, fp) != (size_t) size) { - free(data); - data = NULL; - } else { - data[size] = '\0'; - } + FILE *fp; + char *data = NULL; + if ((fp = fopen(path, "rb")) == NULL) { + } else if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + } else { + long size = ftell(fp); + if (size > 0 && (data = (char *) malloc(size + 1)) != NULL) { + fseek(fp, 0, SEEK_SET); /* Some platforms might not have rewind(), Oo */ + if (fread(data, 1, size, fp) != (size_t) size) { + free(data); + data = NULL; + } else { + data[size] = '\0'; + } + } + fclose(fp); } - fclose(fp); - } - return data; + return data; } struct json_setf_data { - const char *json_path; - const char *base; /* Pointer to the source JSON string */ - int matched; /* Matched part of json_path */ - int pos; /* Offset of the mutated value begin */ - int end; /* Offset of the mutated value end */ - int prev; /* Offset of the previous token end */ + const char *json_path; + const char *base; /* Pointer to the source JSON string */ + int matched; /* Matched part of json_path */ + int pos; /* Offset of the mutated value begin */ + int end; /* Offset of the mutated value end */ + int prev; /* Offset of the previous token end */ }; static int get_matched_prefix_len(const char *s1, const char *s2) { - int i = 0; - while (s1[i] && s2[i] && s1[i] == s2[i]) i++; - return i; + int i = 0; + while (s1[i] && s2[i] && s1[i] == s2[i]) i++; + return i; } static void json_vsetf_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct json_setf_data *data = (struct json_setf_data *) userdata; - int off, len = get_matched_prefix_len(path, data->json_path); - if (t->ptr == NULL) return; - off = t->ptr - data->base; - if (len > data->matched) data->matched = len; + struct json_setf_data *data = (struct json_setf_data *) userdata; + int off, len = get_matched_prefix_len(path, data->json_path); + if (t->ptr == NULL) return; + off = t->ptr - data->base; + if (len > data->matched) data->matched = len; - /* - * If there is no exact path match, set the mutation position to tbe end - * of the object or array - */ - if (len < data->matched && data->pos == 0 && - (t->type == JSON_TYPE_OBJECT_END || t->type == JSON_TYPE_ARRAY_END)) { - data->pos = data->end = data->prev; - } + /* + * If there is no exact path match, set the mutation position to tbe end + * of the object or array + */ + if (len < data->matched && data->pos == 0 && + (t->type == JSON_TYPE_OBJECT_END || t->type == JSON_TYPE_ARRAY_END)) { + data->pos = data->end = data->prev; + } - /* Exact path match. Set mutation position to the value of this token */ - if (strcmp(path, data->json_path) == 0 && t->type != JSON_TYPE_OBJECT_START && - t->type != JSON_TYPE_ARRAY_START) { - data->pos = off; - data->end = off + t->len; - } + /* Exact path match. Set mutation position to the value of this token */ + if (strcmp(path, data->json_path) == 0 && t->type != JSON_TYPE_OBJECT_START && + t->type != JSON_TYPE_ARRAY_START) { + data->pos = off; + data->end = off + t->len; + } - /* - * For deletion, we need to know where the previous value ends, because - * we don't know where matched value key starts. - * When the mutation position is not yet set, remember each value end. - * When the mutation position is already set, but it is at the beginning - * of the object/array, we catch the end of the object/array and see - * whether the object/array start is closer then previously stored prev. - */ - if (data->pos == 0) { - data->prev = off + t->len; /* pos is not yet set */ - } else if ((t->ptr[0] == '[' || t->ptr[0] == '{') && off + 1 < data->pos && - off + 1 > data->prev) { - data->prev = off + 1; - } - (void) name; - (void) name_len; + /* + * For deletion, we need to know where the previous value ends, because + * we don't know where matched value key starts. + * When the mutation position is not yet set, remember each value end. + * When the mutation position is already set, but it is at the beginning + * of the object/array, we catch the end of the object/array and see + * whether the object/array start is closer then previously stored prev. + */ + if (data->pos == 0) { + data->prev = off + t->len; /* pos is not yet set */ + } else if ((t->ptr[0] == '[' || t->ptr[0] == '{') && off + 1 < data->pos && + off + 1 > data->prev) { + data->prev = off + 1; + } + (void) name; + (void) name_len; } int json_vsetf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, va_list ap) WEAK; int json_vsetf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, va_list ap) { - struct json_setf_data data; - memset(&data, 0, sizeof(data)); - data.json_path = json_path; - data.base = s; - data.end = len; - json_walk(s, len, json_vsetf_cb, &data); - if (json_fmt == NULL) { - /* Deletion codepath */ - json_printf(out, "%.*s", data.prev, s); - /* Trim comma after the value that begins at object/array start */ - if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { - int i = data.end; - while (i < len && json_isspace(s[i])) i++; - if (s[i] == ',') data.end = i + 1; /* Point after comma */ + struct json_setf_data data; + memset(&data, 0, sizeof(data)); + data.json_path = json_path; + data.base = s; + data.end = len; + json_walk(s, len, json_vsetf_cb, &data); + if (json_fmt == NULL) { + /* Deletion codepath */ + json_printf(out, "%.*s", data.prev, s); + /* Trim comma after the value that begins at object/array start */ + if (s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { + int i = data.end; + while (i < len && json_isspace(s[i])) i++; + if (s[i] == ',') data.end = i + 1; /* Point after comma */ + } + json_printf(out, "%.*s", len - data.end, s + data.end); + } else { + /* Modification codepath */ + int n, off = data.matched, depth = 0; + + /* Print the unchanged beginning */ + json_printf(out, "%.*s", data.pos, s); + + /* Add missing keys */ + while ((n = strcspn(&json_path[off], ".[")) > 0) { + if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) { + json_printf(out, ","); + } + if (off > 0 && json_path[off - 1] != '.') break; + json_printf(out, "%.*Q:", n, json_path + off); + off += n; + if (json_path[off] != '\0') { + json_printf(out, "%c", json_path[off] == '.' ? '{' : '['); + depth++; + off++; + } + } + /* Print the new value */ + json_vprintf(out, json_fmt, ap); + + /* Close brackets/braces of the added missing keys */ + for (; off > data.matched; off--) { + int ch = json_path[off]; + const char *p = ch == '.' ? "}" : ch == '[' ? "]" : ""; + json_printf(out, "%s", p); + } + + /* Print the rest of the unchanged string */ + json_printf(out, "%.*s", len - data.end, s + data.end); } - json_printf(out, "%.*s", len - data.end, s + data.end); - } else { - /* Modification codepath */ - int n, off = data.matched, depth = 0; - - /* Print the unchanged beginning */ - json_printf(out, "%.*s", data.pos, s); - - /* Add missing keys */ - while ((n = strcspn(&json_path[off], ".[")) > 0) { - if (s[data.prev - 1] != '{' && s[data.prev - 1] != '[' && depth == 0) { - json_printf(out, ","); - } - if (off > 0 && json_path[off - 1] != '.') break; - json_printf(out, "%.*Q:", n, json_path + off); - off += n; - if (json_path[off] != '\0') { - json_printf(out, "%c", json_path[off] == '.' ? '{' : '['); - depth++; - off++; - } - } - /* Print the new value */ - json_vprintf(out, json_fmt, ap); - - /* Close brackets/braces of the added missing keys */ - for (; off > data.matched; off--) { - int ch = json_path[off]; - const char *p = ch == '.' ? "}" : ch == '[' ? "]" : ""; - json_printf(out, "%s", p); - } - - /* Print the rest of the unchanged string */ - json_printf(out, "%.*s", len - data.end, s + data.end); - } - return data.end > data.pos ? 1 : 0; + return data.end > data.pos ? 1 : 0; } int json_setf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, ...) WEAK; int json_setf(const char *s, int len, struct json_out *out, const char *json_path, const char *json_fmt, ...) { - int result; - va_list ap; - va_start(ap, json_fmt); - result = json_vsetf(s, len, out, json_path, json_fmt, ap); - va_end(ap); - return result; + int result; + va_list ap; + va_start(ap, json_fmt); + result = json_vsetf(s, len, out, json_path, json_fmt, ap); + va_end(ap); + return result; } struct prettify_data { - struct json_out *out; - int level; - int last_token; + struct json_out *out; + int level; + int last_token; }; static void indent(struct json_out *out, int level) { - while (level-- > 0) out->printer(out, " ", 2); + while (level-- > 0) out->printer(out, " ", 2); } static void print_key(struct prettify_data *pd, const char *path, const char *name, int name_len) { - if (pd->last_token != JSON_TYPE_INVALID && - pd->last_token != JSON_TYPE_ARRAY_START && - pd->last_token != JSON_TYPE_OBJECT_START) { - pd->out->printer(pd->out, ",", 1); - } - if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1); - indent(pd->out, pd->level); - if (path[0] != '\0' && path[strlen(path) - 1] != ']') { - pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, name, (int) name_len); - pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, ": ", 2); - } + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, ",", 1); + } + if (path[0] != '\0') pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + if (path[0] != '\0' && path[strlen(path) - 1] != ']') { + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, name, (int) name_len); + pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, ": ", 2); + } } static void prettify_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct prettify_data *pd = (struct prettify_data *) userdata; - switch (t->type) { - case JSON_TYPE_OBJECT_START: - case JSON_TYPE_ARRAY_START: - print_key(pd, path, name, name_len); - pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_START ? "[" : "{", - 1); - pd->level++; - break; - case JSON_TYPE_OBJECT_END: - case JSON_TYPE_ARRAY_END: - pd->level--; - if (pd->last_token != JSON_TYPE_INVALID && - pd->last_token != JSON_TYPE_ARRAY_START && - pd->last_token != JSON_TYPE_OBJECT_START) { - pd->out->printer(pd->out, "\n", 1); - indent(pd->out, pd->level); - } - pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1); - break; - case JSON_TYPE_NUMBER: - case JSON_TYPE_NULL: - case JSON_TYPE_TRUE: - case JSON_TYPE_FALSE: - case JSON_TYPE_STRING: - print_key(pd, path, name, name_len); - if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); - pd->out->printer(pd->out, t->ptr, t->len); - if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); - break; - default: - break; - } - pd->last_token = t->type; + struct prettify_data *pd = (struct prettify_data *) userdata; + switch (t->type) { + case JSON_TYPE_OBJECT_START: + case JSON_TYPE_ARRAY_START: + print_key(pd, path, name, name_len); + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_START ? "[" : "{", + 1); + pd->level++; + break; + case JSON_TYPE_OBJECT_END: + case JSON_TYPE_ARRAY_END: + pd->level--; + if (pd->last_token != JSON_TYPE_INVALID && + pd->last_token != JSON_TYPE_ARRAY_START && + pd->last_token != JSON_TYPE_OBJECT_START) { + pd->out->printer(pd->out, "\n", 1); + indent(pd->out, pd->level); + } + pd->out->printer(pd->out, t->type == JSON_TYPE_ARRAY_END ? "]" : "}", 1); + break; + case JSON_TYPE_NUMBER: + case JSON_TYPE_NULL: + case JSON_TYPE_TRUE: + case JSON_TYPE_FALSE: + case JSON_TYPE_STRING: + print_key(pd, path, name, name_len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + pd->out->printer(pd->out, t->ptr, t->len); + if (t->type == JSON_TYPE_STRING) pd->out->printer(pd->out, "\"", 1); + break; + default: + break; + } + pd->last_token = t->type; } int json_prettify(const char *s, int len, struct json_out *out) WEAK; int json_prettify(const char *s, int len, struct json_out *out) { - struct prettify_data pd = {out, 0, JSON_TYPE_INVALID}; - return json_walk(s, len, prettify_cb, &pd); + struct prettify_data pd = {out, 0, JSON_TYPE_INVALID}; + return json_walk(s, len, prettify_cb, &pd); } int json_prettify_file(const char *file_name) WEAK; int json_prettify_file(const char *file_name) { - int res = -1; - char *s = json_fread(file_name); - FILE *fp; - if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) { - struct json_out out = JSON_OUT_FILE(fp); - res = json_prettify(s, strlen(s), &out); - if (res < 0) { - /* On error, restore the old content */ - fclose(fp); - fp = fopen(file_name, "wb"); - fseek(fp, 0, SEEK_SET); - fwrite(s, 1, strlen(s), fp); - } else { - fputc('\n', fp); + int res = -1; + char *s = json_fread(file_name); + FILE *fp; + if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) { + struct json_out out = JSON_OUT_FILE(fp); + res = json_prettify(s, strlen(s), &out); + if (res < 0) { + /* On error, restore the old content */ + fclose(fp); + fp = fopen(file_name, "wb"); + fseek(fp, 0, SEEK_SET); + fwrite(s, 1, strlen(s), fp); + } else { + fputc('\n', fp); + } + fclose(fp); } - fclose(fp); - } - free(s); - return res; + free(s); + return res; } struct next_data { - void *handle; // Passed handle. Changed if a next entry is found - const char *path; // Path to the iterated object/array - int path_len; // Path length - optimisation - int found; // Non-0 if found the next entry - struct json_token *key; // Object's key - struct json_token *val; // Object's value - int *idx; // Array index + void *handle; // Passed handle. Changed if a next entry is found + const char *path; // Path to the iterated object/array + int path_len; // Path length - optimisation + int found; // Non-0 if found the next entry + struct json_token *key; // Object's key + struct json_token *val; // Object's value + int *idx; // Array index }; static void next_set_key(struct next_data *d, const char *name, int name_len, int is_array) { - if (is_array) { - /* Array. Set index and reset key */ - if (d->key != NULL) { - d->key->len = 0; - d->key->ptr = NULL; + if (is_array) { + /* Array. Set index and reset key */ + if (d->key != NULL) { + d->key->len = 0; + d->key->ptr = NULL; + } + if (d->idx != NULL) *d->idx = atoi(name); + } else { + /* Object. Set key and make index -1 */ + if (d->key != NULL) { + d->key->ptr = name; + d->key->len = name_len; + } + if (d->idx != NULL) *d->idx = -1; } - if (d->idx != NULL) *d->idx = atoi(name); - } else { - /* Object. Set key and make index -1 */ - if (d->key != NULL) { - d->key->ptr = name; - d->key->len = name_len; - } - if (d->idx != NULL) *d->idx = -1; - } } static void json_next_cb(void *userdata, const char *name, size_t name_len, const char *path, const struct json_token *t) { - struct next_data *d = (struct next_data *) userdata; - const char *p = path + d->path_len; - if (d->found) return; - if (d->path_len >= (int) strlen(path)) return; - if (strncmp(d->path, path, d->path_len) != 0) return; - if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */ - if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */ - // {OBJECT,ARRAY}_END types do not pass name, _START does. Save key. - if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) { - next_set_key(d, name, name_len, p[0] == '['); - } else if (d->handle == NULL || d->handle < (void *) t->ptr) { - if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) { - next_set_key(d, name, name_len, p[0] == '['); + struct next_data *d = (struct next_data *) userdata; + const char *p = path + d->path_len; + if (d->found) return; + if (d->path_len >= (int) strlen(path)) return; + if (strncmp(d->path, path, d->path_len) != 0) return; + if (strchr(p + 1, '.') != NULL) return; /* More nested objects - skip */ + if (strchr(p + 1, '[') != NULL) return; /* Ditto for arrays */ + // {OBJECT,ARRAY}_END types do not pass name, _START does. Save key. + if (t->type == JSON_TYPE_OBJECT_START || t->type == JSON_TYPE_ARRAY_START) { + next_set_key(d, name, name_len, p[0] == '['); + } else if (d->handle == NULL || d->handle < (void *) t->ptr) { + if (t->type != JSON_TYPE_OBJECT_END && t->type != JSON_TYPE_ARRAY_END) { + next_set_key(d, name, name_len, p[0] == '['); + } + if (d->val != NULL) *d->val = *t; + d->handle = (void *) t->ptr; + d->found = 1; } - if (d->val != NULL) *d->val = *t; - d->handle = (void *) t->ptr; - d->found = 1; - } } static void *json_next(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val, int *i) { - struct json_token tmpval, *v = val == NULL ? &tmpval : val; - struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; - int tmpidx, *pidx = i == NULL ? &tmpidx : i; - struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; - json_walk(s, len, json_next_cb, &data); - return data.found ? data.handle : NULL; + struct json_token tmpval, *v = val == NULL ? &tmpval : val; + struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; + int tmpidx, *pidx = i == NULL ? &tmpidx : i; + struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; + json_walk(s, len, json_next_cb, &data); + return data.found ? data.handle : NULL; } void *json_next_key(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val) WEAK; void *json_next_key(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val) { - return json_next(s, len, handle, path, key, val, NULL); + return json_next(s, len, handle, path, key, val, NULL); } void *json_next_elem(const char *s, int len, void *handle, const char *path, int *idx, struct json_token *val) WEAK; void *json_next_elem(const char *s, int len, void *handle, const char *path, int *idx, struct json_token *val) { - return json_next(s, len, handle, path, NULL, val, idx); + return json_next(s, len, handle, path, NULL, val, idx); } static int json_sprinter(struct json_out *out, const char *str, size_t len) { - size_t old_len = out->u.buf.buf == NULL ? 0 : strlen(out->u.buf.buf); - size_t new_len = len + old_len; - char *p = (char *) realloc(out->u.buf.buf, new_len + 1); - if (p != NULL) { - memcpy(p + old_len, str, len); - p[new_len] = '\0'; - out->u.buf.buf = p; - } - return len; + size_t old_len = out->u.buf.buf == NULL ? 0 : strlen(out->u.buf.buf); + size_t new_len = len + old_len; + char *p = (char *) realloc(out->u.buf.buf, new_len + 1); + if (p != NULL) { + memcpy(p + old_len, str, len); + p[new_len] = '\0'; + out->u.buf.buf = p; + } + return len; } char *json_vasprintf(const char *fmt, va_list ap) WEAK; char *json_vasprintf(const char *fmt, va_list ap) { - struct json_out out; - memset(&out, 0, sizeof(out)); - out.printer = json_sprinter; - json_vprintf(&out, fmt, ap); - return out.u.buf.buf; + struct json_out out; + memset(&out, 0, sizeof(out)); + out.printer = json_sprinter; + json_vprintf(&out, fmt, ap); + return out.u.buf.buf; } char *json_asprintf(const char *fmt, ...) WEAK; char *json_asprintf(const char *fmt, ...) { - char *result = NULL; - va_list ap; - va_start(ap, fmt); - result = json_vasprintf(fmt, ap); - va_end(ap); - return result; + char *result = NULL; + va_list ap; + va_start(ap, fmt); + result = json_vasprintf(fmt, ap); + va_end(ap); + return result; } diff --git a/armsrc/frozen.h b/armsrc/frozen.h index cfe651e12..49183ee7d 100644 --- a/armsrc/frozen.h +++ b/armsrc/frozen.h @@ -36,18 +36,18 @@ enum { false = 0, true = 1 }; /* JSON token type */ enum json_token_type { - JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ - JSON_TYPE_STRING, - JSON_TYPE_NUMBER, - JSON_TYPE_TRUE, - JSON_TYPE_FALSE, - JSON_TYPE_NULL, - JSON_TYPE_OBJECT_START, - JSON_TYPE_OBJECT_END, - JSON_TYPE_ARRAY_START, - JSON_TYPE_ARRAY_END, + JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */ + JSON_TYPE_STRING, + JSON_TYPE_NUMBER, + JSON_TYPE_TRUE, + JSON_TYPE_FALSE, + JSON_TYPE_NULL, + JSON_TYPE_OBJECT_START, + JSON_TYPE_OBJECT_END, + JSON_TYPE_ARRAY_START, + JSON_TYPE_ARRAY_END, - JSON_TYPES_CNT + JSON_TYPES_CNT }; /* @@ -55,9 +55,9 @@ enum json_token_type { * `json_scanf()` with the format specifier `%T`. */ struct json_token { - const char *ptr; /* Points to the beginning of the value */ - int len; /* Value length */ - enum json_token_type type; /* Type of the token, possible values are above */ + const char *ptr; /* Points to the beginning of the value */ + int len; /* Value length */ + enum json_token_type type; /* Type of the token, possible values are above */ }; #define JSON_INVALID_TOKEN \ @@ -110,16 +110,16 @@ int json_walk(const char *json_string, int json_string_length, * struct json_out abstracts output, allowing alternative printing plugins. */ struct json_out { - int (*printer)(struct json_out *, const char *str, size_t len); - union { - struct { - char *buf; - size_t size; - size_t len; - } buf; - void *data; - FILE *fp; - } u; + int (*printer)(struct json_out *, const char *str, size_t len); + union { + struct { + char *buf; + size_t size; + size_t len; + } buf; + void *data; + FILE *fp; + } u; }; extern int json_printer_buf(struct json_out *, const char *, size_t); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2618bec44..b17df8424 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -464,7 +464,7 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t } -// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. +// Thinfilm, Kovio mangels ISO14443A in the way that they don't use start bit nor parity bits. RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { Demod.twoBits = (Demod.twoBits << 8) | bit; @@ -496,44 +496,44 @@ RAMFUNC int ManchesterDecoding_Thinfilm(uint8_t bit) { } } else { - if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision - if (!Demod.collisionPos) { - Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; - } - } // modulation in first half only - Sequence D = 1 + if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision + if (!Demod.collisionPos) { + Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; + } + } // modulation in first half only - Sequence D = 1 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg + if (Demod.bitCount == 8) { // if we decoded a full byte + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.bitCount = 0; + Demod.shiftReg = 0; + } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4; + } else { // no modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg << 1) | 0x1; // in both cases, add a 1 to the shiftreg - if (Demod.bitCount == 8) { // if we decoded a full byte + Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg + if (Demod.bitCount >= 8) { // if we decoded a full byte Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); Demod.bitCount = 0; Demod.shiftReg = 0; } - Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1) - 4; - } else { // no modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg << 1); // add a 0 to the shiftreg - if (Demod.bitCount >= 8) { // if we decoded a full byte - Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); - Demod.bitCount = 0; - Demod.shiftReg = 0; - } - Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); - } else { // no modulation in both halves - End of communication - if (Demod.bitCount > 0) { // there are some remaining data bits - Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits - Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output - return true; - } - if (Demod.len) { - return true; // we are finished with decoding the raw data sequence - } else { // nothing received. Start over - DemodReset(); - } + Demod.endTime = Demod.startTime + 8 * (8 * Demod.len + Demod.bitCount + 1); + } else { // no modulation in both halves - End of communication + if (Demod.bitCount > 0) { // there are some remaining data bits + Demod.shiftReg <<= (8 - Demod.bitCount); // left align the decoded bits + Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output + return true; + } + if (Demod.len) { + return true; // we are finished with decoding the raw data sequence + } else { // nothing received. Start over + DemodReset(); } } } + } return false; // not finished yet, need more data } @@ -655,7 +655,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { Uart.len, Uart.startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, Uart.endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.parity, + Uart.parity, true)) break; } /* ready to receive another command. */ @@ -2007,7 +2007,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start } //----------------------------------------------------------------------------- -// Kovio - Thinfilm barcode. TAG-TALK-FIRST - +// Kovio - Thinfilm barcode. TAG-TALK-FIRST - // Wait a certain time for tag response // If a response is captured return TRUE // If it takes too long return FALSE @@ -2041,7 +2041,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec // log LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false); return true; - } + } } // timeout already in ms + 10ms guard time diff --git a/armsrc/nprintf.c b/armsrc/nprintf.c index b6b200549..62e6ea8c0 100644 --- a/armsrc/nprintf.c +++ b/armsrc/nprintf.c @@ -119,210 +119,201 @@ // output function type -typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); +typedef void (*out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen); // wrapper (used as buffer) for output function type typedef struct { - void (*fct)(char character, void* arg); - void* arg; + void (*fct)(char character, void *arg); + void *arg; } out_fct_wrap_type; // internal buffer output -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) -{ - if (idx < maxlen) { - ((char*)buffer)[idx] = character; - } +static inline void _out_buffer(char character, void *buffer, size_t idx, size_t maxlen) { + if (idx < maxlen) { + ((char *)buffer)[idx] = character; + } } // internal null output -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)character; (void)buffer; (void)idx; (void)maxlen; +static inline void _out_null(char character, void *buffer, size_t idx, size_t maxlen) { + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; } // internal _putchar wrapper -static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)buffer; (void)idx; (void)maxlen; - if (character) { - _putchar(character); - } +static inline void _out_char(char character, void *buffer, size_t idx, size_t maxlen) { + (void)buffer; + (void)idx; + (void)maxlen; + if (character) { + _putchar(character); + } } // internal output function wrapper -static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) -{ - (void)idx; (void)maxlen; - if (character) { - // buffer is the output fct pointer - ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); - } +static inline void _out_fct(char character, void *buffer, size_t idx, size_t maxlen) { + (void)idx; + (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type *)buffer)->fct(character, ((out_fct_wrap_type *)buffer)->arg); + } } // internal secure strlen // \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char* str, size_t maxsize) -{ - const char* s; - for (s = str; *s && maxsize--; ++s); - return (unsigned int)(s - str); +static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { + const char *s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); } // internal test if char is a digit (0-9) // \return true if char is a digit -static inline bool _is_digit(char ch) -{ - return (ch >= '0') && (ch <= '9'); +static inline bool _is_digit(char ch) { + return (ch >= '0') && (ch <= '9'); } // internal ASCII string to unsigned int conversion -static unsigned int _atoi(const char** str) -{ - unsigned int i = 0U; - while (_is_digit(**str)) { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; +static unsigned int _atoi(const char **str) { + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; } // output the specified string in reverse, taking care of any zero-padding -static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; +static size_t _out_rev(out_fct_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) { + const size_t start_idx = idx; - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } } - } - // reverse string - while (len) { - out(buf[--len], buffer, idx++, maxlen); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); } - } - return idx; + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; } // internal itoa format -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) -{ - // pad leading zeros - if (!(flags & FLAGS_LEFT)) { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; +static size_t _ntoa_format(out_fct_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) { + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } } - while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - // handle hash - if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { - len--; - if (len && (base == 16U)) { - len--; - } - } - if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'b'; + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } } + if (len < PRINTF_NTOA_BUFFER_SIZE) { - buf[len++] = '0'; + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } } - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } // internal itoa for 'long' type -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; +static size_t _ntoa_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); } // internal itoa for 'long long' type #if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; +static size_t _ntoa_long_long(out_fct_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); } #endif // PRINTF_SUPPORT_LONG_LONG @@ -331,584 +322,576 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t #if defined(PRINTF_SUPPORT_EXPONENTIAL) // forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); #endif // internal ftoa for fixed decimal floating point -static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[PRINTF_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; +static size_t _ftoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; - // powers of 10 - static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - // test for special values - if (value != value) - return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); - if (value < -DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); - if (value > DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); - // test for very large values - // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad - if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { #if defined(PRINTF_SUPPORT_EXPONENTIAL) - return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); #else - return 0U; + return 0U; #endif - } - - // test for negative - bool negative = false; - if (value < 0) { - negative = true; - value = 0 - value; - } - - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { - buf[len++] = '0'; - prec--; - } - - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; - - if (diff > 0.5) { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) { - frac = 0; - ++whole; } - } - else if (diff < 0.5) { - } - else if ((frac == 0U) || (frac & 1U)) { - // if halfway, round up if odd OR if last digit is 0 - ++frac; - } - if (prec == 0U) { - diff = value - (double)whole; - if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; } - } - else { - unsigned int count = prec; - // now do fractional part, as an unsigned number + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) { + frac = 0; + ++whole; + } + } else if (diff < 0.5) { + } else if ((frac == 0U) || (frac & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed while (len < PRINTF_FTOA_BUFFER_SIZE) { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) { - break; - } + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } } - // add extra 0s - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { - buf[len++] = '0'; + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } } + if (len < PRINTF_FTOA_BUFFER_SIZE) { - // add decimal - buf[len++] = '.'; + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } } - } - // do whole part, number is reversed - while (len < PRINTF_FTOA_BUFFER_SIZE) { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) { - break; - } - } - - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { - if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - - if (len < PRINTF_FTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } #if defined(PRINTF_SUPPORT_EXPONENTIAL) // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - // check for NaN and special values - if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { - return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); - } - - // determine the sign - const bool negative = value < 0; - if (negative) { - value = -value; - } - - // default precision - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - - // determine the decimal exponent - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - union { - uint64_t U; - double F; - } conv; - - conv.F = value; - int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 - conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) - // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 - int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); - // now we want to compute 10^expval but we want to be sure it won't overflow - exp2 = (int)(expval * 3.321928094887362 + 0.5); - const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - conv.U = (uint64_t)(exp2 + 1023) << 52U; - // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - // correct for rounding errors - if (value < conv.F) { - expval--; - conv.F /= 10; - } - - // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters - unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; - - // in "%g" mode, "prec" is the number of *significant figures* not decimals - if (flags & FLAGS_ADAPT_EXP) { - // do we want to fall-back to "%f" mode? - if ((value >= 1e-4) && (value < 1e6)) { - if ((int)prec > expval) { - prec = (unsigned)((int)prec - expval - 1); - } - else { - prec = 0; - } - flags |= FLAGS_PRECISION; // make sure _ftoa respects precision - // no characters in exponent - minwidth = 0U; - expval = 0; +static size_t _etoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); } - else { - // we use one sigfig for the whole part - if ((prec > 0) && (flags & FLAGS_PRECISION)) { - --prec; - } + + // determine the sign + const bool negative = value < 0; + if (negative) { + value = -value; } - } - // will everything fit? - unsigned int fwidth = width; - if (width > minwidth) { - // we didn't fall-back so subtract the characters required for the exponent - fwidth -= minwidth; - } else { - // not enough characters, so go back to default sizing - fwidth = 0U; - } - if ((flags & FLAGS_LEFT) && minwidth) { - // if we're padding on the right, DON'T pad the floating part - fwidth = 0U; - } - - // rescale the float value - if (expval) { - value /= conv.F; - } - - // output the floating part - const size_t start_idx = idx; - idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); - - // output the exponent part - if (minwidth) { - // output the exponential symbol - out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); - // output the exponent value - idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); - // might need to right-pad spaces - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + // default precision + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; } - } - return idx; + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) { + if ((int)prec > expval) { + prec = (unsigned)((int)prec - expval - 1); + } else { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } else { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } else { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; } #endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf -static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) -{ - unsigned int flags, width, precision, n; - size_t idx = 0U; +static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const char *format, va_list va) { + unsigned int flags, width, precision, n; + size_t idx = 0U; - if (!buffer) { - // use null output function - out = _out_null; - } - - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else { - // yes, evaluate it - format++; + if (!buffer) { + // use null output function + out = _out_null; } - // evaluate flags - flags = 0U; - do { - switch (*format) { - case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; - case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; - case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; - case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; - case '#': flags |= FLAGS_HASH; format++; n = 1U; break; - default : n = 0U; break; - } - } while (n); - - // evaluate width field - width = 0U; - if (_is_digit(*format)) { - width = _atoi(&format); - } - else if (*format == '*') { - const int w = va_arg(va, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else { - width = (unsigned int)w; - } - format++; - } - - // evaluate precision field - precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - format++; - if (_is_digit(*format)) { - precision = _atoi(&format); - } - else if (*format == '*') { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } - - // evaluate length field - switch (*format) { - case 'l' : - flags |= FLAGS_LONG; - format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; } - break; - case 'h' : - flags |= FLAGS_SHORT; - format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default : + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int) - w; + } else { + width = (unsigned int)w; + } + format++; } - break; + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; #if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; #endif - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default : - break; - } - - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } - else if (*format == 'o') { - base = 8U; - } - else if (*format == 'b') { - base = 2U; - } - else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; } - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - } + // evaluate specifier + switch (*format) { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } else if (*format == 'o') { + base = 8U; + } else if (*format == 'b') { + base = 2U; + } else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; - } + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); #endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(va, long); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else { - const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else { - // unsigned - if (flags & FLAGS_LONG_LONG) { + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } else { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); #endif - } - else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } + } else if (flags & FLAGS_LONG) { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } else { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } #if defined(PRINTF_SUPPORT_FLOAT) - case 'f' : - case 'F' : - if (*format == 'F') flags |= FLAGS_UPPERCASE; - idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'f' : + case 'F' : + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; #if defined(PRINTF_SUPPORT_EXPONENTIAL) - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; - idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; #endif // PRINTF_SUPPORT_EXPONENTIAL #endif // PRINTF_SUPPORT_FLOAT - case 'c' : { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 'c' : { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 's' : { - const char* p = va_arg(va, char*); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 's' : { + const char *p = va_arg(va, char *); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 'p' : { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; + case 'p' : { + width = sizeof(void *) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); - } - else { + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags); + } else { #endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags); #if defined(PRINTF_SUPPORT_LONG_LONG) - } + } #endif - format++; - break; - } + format++; + break; + } - case '%' : - out('%', buffer, idx++, maxlen); - format++; - break; + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; - default : - out(*format, buffer, idx++, maxlen); - format++; - break; + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } } - } - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - // return written chars without terminating \0 - return (int)idx; + // return written chars without terminating \0 + return (int)idx; } /////////////////////////////////////////////////////////////////////////////// -int printf_(const char* format, ...) -{ - va_list va; - va_start(va, format); - char buffer[1]; - const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int printf_(const char *format, ...) { + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t) -1, format, va); + va_end(va); + return ret; } -int sprintf_(char* buffer, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); - va_end(va); - return ret; +int sprintf_(char *buffer, const char *format, ...) { + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t) -1, format, va); + va_end(va); + return ret; } -int snprintf_(char* buffer, size_t count, const char* format, ...) -{ - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); - va_end(va); - return ret; +int snprintf_(char *buffer, size_t count, const char *format, ...) { + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; } -int vprintf_(const char* format, va_list va) -{ - char buffer[1]; - return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +int vprintf_(const char *format, va_list va) { + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t) -1, format, va); } -int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) -{ - return _vsnprintf(_out_buffer, buffer, count, format, va); +int vsnprintf_(char *buffer, size_t count, const char *format, va_list va) { + return _vsnprintf(_out_buffer, buffer, count, format, va); } -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) -{ - va_list va; - va_start(va, format); - const out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; +int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) { + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char *)(uintptr_t)&out_fct_wrap, (size_t) -1, format, va); + va_end(va); + return ret; } diff --git a/armsrc/nprintf.h b/armsrc/nprintf.h index 8f7a4c8fe..3cfdb4134 100644 --- a/armsrc/nprintf.h +++ b/armsrc/nprintf.h @@ -10,10 +10,10 @@ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -58,7 +58,7 @@ void _putchar(char character); * \return The number of characters that are written into the array, not counting the terminating null character */ #define printf printf_ -int printf_(const char* format, ...); +int printf_(const char *format, ...); /** @@ -69,7 +69,7 @@ int printf_(const char* format, ...); * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ #define sprintf sprintf_ -int sprintf_(char* buffer, const char* format, ...); +int sprintf_(char *buffer, const char *format, ...); /** @@ -84,8 +84,8 @@ int sprintf_(char* buffer, const char* format, ...); */ #define snprintf snprintf_ #define vsnprintf vsnprintf_ -int snprintf_(char* buffer, size_t count, const char* format, ...); -int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); +int snprintf_(char *buffer, size_t count, const char *format, ...); +int vsnprintf_(char *buffer, size_t count, const char *format, va_list va); /** @@ -95,7 +95,7 @@ int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ #define vprintf vprintf_ -int vprintf_(const char* format, va_list va); +int vprintf_(const char *format, va_list va); /** @@ -106,7 +106,7 @@ int vprintf_(const char* format, va_list va); * \param format A string that specifies the format of the output * \return The number of characters that are sent to the output function, not counting the terminating null character */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); +int fctprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...); #ifdef __cplusplus diff --git a/armsrc/string.c b/armsrc/string.c index 7931b9a94..4caa027a2 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -197,56 +197,50 @@ char *strtok(char *s, const char *delim) { } -char *strchr(const char *s, int c) -{ +char *strchr(const char *s, int c) { while (*s != (char)c) if (!*s++) return 0; return (char *)s; } -size_t strspn(const char *s1, const char *s2) -{ - size_t ret=0; - while(*s1 && strchr(s2,*s1++)) +size_t strspn(const char *s1, const char *s2) { + size_t ret = 0; + while (*s1 && strchr(s2, *s1++)) ret++; - return ret; -} - -char *strrchr(const char *s, int c) -{ - const char* ret=0; - do { - if( *s == (char)c ) - ret=s; - } while(*s++); - return (char *)ret; -} - -size_t strcspn(const char *s1, const char *s2) -{ - size_t ret=0; - while(*s1) - if(strchr(s2,*s1)) - return ret; - else - s1++,ret++; return ret; } -char *strpbrk(const char *s1, const char *s2) -{ - while(*s1) - if(strchr(s2, *s1++)) - return (char*)--s1; +char *strrchr(const char *s, int c) { + const char *ret = 0; + do { + if (*s == (char)c) + ret = s; + } while (*s++); + return (char *)ret; +} + +size_t strcspn(const char *s1, const char *s2) { + size_t ret = 0; + while (*s1) + if (strchr(s2, *s1)) + return ret; + else + s1++, ret++; + return ret; +} + +char *strpbrk(const char *s1, const char *s2) { + while (*s1) + if (strchr(s2, *s1++)) + return (char *)--s1; return 0; } -int strncmp(const char* s1, const char* s2, size_t n) -{ - while(n--) - if(*s1++!=*s2++) - return *(unsigned char*)(s1 - 1) - *(unsigned char*)(s2 - 1); +int strncmp(const char *s1, const char *s2, size_t n) { + while (n--) + if (*s1++ != *s2++) + return *(unsigned char *)(s1 - 1) - *(unsigned char *)(s2 - 1); return 0; } @@ -255,97 +249,87 @@ int strncmp(const char* s1, const char* s2, size_t n) #define isspace(a) __extension__ ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); }) -unsigned long strtoul(const char *p, char **out_p, int base) -{ - unsigned long v = 0; +unsigned long strtoul(const char *p, char **out_p, int base) { + unsigned long v = 0; - while (isspace(*p)) - p++; - if (((base == 16) || (base == 0)) && - ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) - { - p += 2; - base = 16; - } - if (base == 0) - { - if (*p == '0') - base = 8; - else - base = 10; - } - while (1) - { - char c = *p; - if ((c >= '0') && (c <= '9') && (c - '0' < base)) - v = (v * base) + (c - '0'); - else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) - v = (v * base) + (c - 'a' + 10); - else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) - v = (v * base) + (c - 'A' + 10); - else - break; - p++; - } + while (isspace(*p)) + p++; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) { + p += 2; + base = 16; + } + if (base == 0) { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } - if (out_p) *out_p = (char*)p; - return v; + if (out_p) *out_p = (char *)p; + return v; } -long strtol(const char *p, char **out_p, int base) -{ - long v = 0; - int is_neg = 0; +long strtol(const char *p, char **out_p, int base) { + long v = 0; + int is_neg = 0; - while (isspace(*p)) - p++; - if (*p == '-') - is_neg = 1, p++; - else if (*p == '+') - is_neg = 0; - if (((base == 16) || (base == 0)) && - ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) - { - p += 2; - base = 16; - } - if (base == 0) - { - if (*p == '0') - base = 8; - else - base = 10; - } - while (1) - { - char c = *p; - if ((c >= '0') && (c <= '9') && (c - '0' < base)) - v = (v * base) + (c - '0'); - else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) - v = (v * base) + (c - 'a' + 10); - else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) - v = (v * base) + (c - 'A' + 10); - else - break; - p++; - } - if (is_neg) - v = -v; - if (out_p) *out_p = (char*)p; - return v; + while (isspace(*p)) + p++; + if (*p == '-') + is_neg = 1, p++; + else if (*p == '+') + is_neg = 0; + if (((base == 16) || (base == 0)) && + ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) { + p += 2; + base = 16; + } + if (base == 0) { + if (*p == '0') + base = 8; + else + base = 10; + } + while (1) { + char c = *p; + if ((c >= '0') && (c <= '9') && (c - '0' < base)) + v = (v * base) + (c - '0'); + else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base)) + v = (v * base) + (c - 'a' + 10); + else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base)) + v = (v * base) + (c - 'A' + 10); + else + break; + p++; + } + if (is_neg) + v = -v; + if (out_p) *out_p = (char *)p; + return v; } -char c_tolower(int c) -{ +char c_tolower(int c) { // (int)a = 97, (int)A = 65 // (a)97 - (A)65 = 32 // therefore 32 + 65 = a return c > 64 && c < 91 ? c + 32 : c; } -char c_isprint (unsigned char c) -{ - if ( c >= 0x20 && c <= 0x7e ) +char c_isprint(unsigned char c) { + if (c >= 0x20 && c <= 0x7e) return 1; return 0; } diff --git a/armsrc/string.h b/armsrc/string.h index 5338ae6b3..5e3e31137 100644 --- a/armsrc/string.h +++ b/armsrc/string.h @@ -32,9 +32,9 @@ size_t strspn(const char *s1, const char *s2); char *strrchr(const char *s, int c); size_t strcspn(const char *s1, const char *s2); char *strpbrk(const char *s1, const char *s2); -int strncmp(const char * s1, const char * s2, size_t n); +int strncmp(const char *s1, const char *s2, size_t n); char c_tolower(int c); -char c_isprint (unsigned char c); +char c_isprint(unsigned char c); diff --git a/client/cmdhfthinfilm.c b/client/cmdhfthinfilm.c index 336843b92..0b2642b1b 100644 --- a/client/cmdhfthinfilm.c +++ b/client/cmdhfthinfilm.c @@ -27,28 +27,28 @@ static int usage_thinfilm_info(void) { // https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-barcode.c static int print_barcode(uint8_t *barcode, const size_t barcode_len) { - PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0] ); + PrintAndLogEx(SUCCESS, " Manufacturer : "_YELLOW_("%s") "[0x%02X]", (barcode[0] == 0xB7) ? "Thinfilm" : "unknown", barcode[0]); PrintAndLogEx(SUCCESS, " Data format : "_YELLOW_("%02X"), barcode[1]); uint8_t b1, b2; compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2); bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2); - + PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail")); PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), - sprint_hex(barcode, barcode_len) - ); + sprint_hex(barcode, barcode_len) + ); char s[45]; memset(s, 0x00, sizeof(s)); - + switch (barcode[1]) { case 0: printf("Data Format Field: Reserved for allocation by tag manufacturer\n"); return PM3_SUCCESS; case 1: - snprintf(s, sizeof(s), "http://www." ); + snprintf(s, sizeof(s), "http://www."); break; case 2: snprintf(s, sizeof(s), "https://www."); @@ -60,15 +60,15 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len) { snprintf(s, sizeof(s), "https://"); break; case 5: - PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12) ); + PrintAndLogEx(SUCCESS, "EPC: %s", sprint_hex(barcode + 2, 12)); return PM3_SUCCESS; default: PrintAndLogEx(SUCCESS, "Data Format Field: unknown (%02X)", barcode[1]); - PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2) ); + PrintAndLogEx(SUCCESS, "Data:" _YELLOW_("%s"), sprint_hex(barcode + 2, barcode_len - 2)); return PM3_SUCCESS; } - - snprintf(s + strlen(s), barcode_len - 3, (const char*)&barcode[2] , barcode_len - 4); + + snprintf(s + strlen(s), barcode_len - 3, (const char *)&barcode[2], barcode_len - 4); for (uint8_t i = 0; i < strlen(s); i++) { @@ -108,8 +108,8 @@ static int CmdHfThinFilmInfo(const char *Cmd) { } int infoThinFilm(void) { - - clearCommandBuffer(); + + clearCommandBuffer(); SendCommandNG(CMD_THINFILM_READ, NULL, 0); PacketResponseNG resp; @@ -117,9 +117,9 @@ int infoThinFilm(void) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } - - if ( resp.status == PM3_SUCCESS ) { - print_barcode( resp.data.asBytes, resp.length ); + + if (resp.status == PM3_SUCCESS) { + print_barcode(resp.data.asBytes, resp.length); } return resp.status; diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index ab3fcb69d..3aebcd673 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -43,7 +43,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint SendCommandOLD(CMD_READER_ISO_14443a, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0, cmd, len); PacketResponseNG resp; - + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; @@ -98,10 +98,10 @@ static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { // read all of the static memory of a selected Topaz tag. static int topaz_rall(uint8_t *uid, uint8_t *response) { - uint16_t resp_len = 0; + uint16_t resp_len = 0; uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(&rall_cmd[3], uid, 4); - + if (topaz_send_cmd(rall_cmd, sizeof(rall_cmd), response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RALL failed @@ -119,7 +119,7 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) read8_cmd[1] = blockno; memcpy(&read8_cmd[10], uid, 4); - + if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // READ8 failed @@ -136,7 +136,7 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data rseg_cmd[1] = segno << 4; memcpy(&rseg_cmd[10], uid, 4); - + if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // RSEG failed @@ -420,7 +420,7 @@ static int CmdHFTopazReader(const char *Cmd) { (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", (rid_response[0] & 0x0F) == 0x01 ? "static" : "dynamic"); - + PrintAndLogEx(NORMAL, "HR1 : %02x", rid_response[1]); status = topaz_rall(uid_echo, rall_response); @@ -475,7 +475,7 @@ static int CmdHFTopazReader(const char *Cmd) { sprintf(&line[3 * j], "%02x ", topaz_tag.data_blocks[0x0e][j]); } PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index f9b1470fc..f97090628 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -32,9 +32,9 @@ reg [7:0] pck_divider; reg clk_state; // Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) -wire tag_modulation; +wire tag_modulation; assign tag_modulation = ssp_dout & !lf_field; -wire reader_modulation; +wire reader_modulation; assign reader_modulation = !ssp_dout & lf_field & clk_state; assign pwr_oe1 = 1'b0; // not used in LF mode assign pwr_oe2 = 1'b0; //tag_modulation;