Просмотр исходного кода

Implement cast frozen %B type to char

PUBLISHED_FROM=db54134c9641e3bc618c52f7b74fab7bd2b96821
Ruslan Valiullin 8 лет назад
Родитель
Сommit
e76c7312e4
3 измененных файлов с 34 добавлено и 2 удалено
  1. 11 1
      frozen.c
  2. 8 1
      frozen.h
  3. 15 0
      unit_test.c

+ 11 - 1
frozen.c

@@ -879,7 +879,17 @@ static void json_scanf_cb(void *callback_data, const char *name,
   switch (info->type) {
     case 'B':
       info->num_conversions++;
-      *(int *) info->target = (token->type == JSON_TYPE_TRUE ? 1 : 0);
+      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 {

+ 8 - 1
frozen.h

@@ -28,6 +28,12 @@ extern "C" {
 #include <stddef.h>
 #include <stdio.h>
 
+#ifdef _WIN32
+typedef int bool;
+#else
+#include <stdbool.h>
+#endif
+
 /* JSON token type */
 enum json_token_type {
   JSON_TYPE_INVALID = 0, /* memsetting to 0 should create INVALID value */
@@ -165,7 +171,8 @@ int json_printf_array(struct json_out *, va_list *ap);
  * 1. Object keys in the format string may be not quoted, e.g. "{key: %d}"
  * 2. Order of keys in an object is irrelevant.
  * 3. Several extra format specifiers are supported:
- *    - %B: consumes `int *`, expects boolean `true` or `false`.
+ *    - %B: consumes `int *` (or 'char *', if sizeof(bool) == sizeof(char)), 
+ *       expects boolean `true` or `false`.
  *    - %Q: consumes `char **`, expects quoted, JSON-encoded string. Scanned
  *       string is malloc-ed, caller must free() the string.
  *    - %V: consumes `char **`, `int *`. Expects base64-encoded string.

+ 15 - 0
unit_test.c

@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 const char *tok_type_names[] = {
     "INVALID", "STRING",       "NUMBER",     "TRUE",        "FALSE",
@@ -555,6 +556,20 @@ static const char *test_scanf(void) {
     free(result);
   }
 
+  {
+    int a = 0;
+    bool b = false;
+    int c = 0xFFFFFFFF;
+    const char *str = "{\"b\":true,\"c\":false,\"a\":2}";
+    ASSERT(json_scanf(str, strlen(str), "{a:%d, b:%B, c:%B}", &a, &b, &c) == 3);
+    ASSERT(a == 2);
+    ASSERT(b == true);
+    if (sizeof(bool) == 1)
+      ASSERT((char)c == false);
+    else
+      ASSERT(c == false);
+  }
+
   return NULL;
 }