Pārlūkot izejas kodu

Make mjs & frozen vc98 & vc2017 friendly

PUBLISHED_FROM=7cde8b374d5e318b5cdd69fc5b4de86b2a9552f5
Бобби 8 gadi atpakaļ
vecāks
revīzija
91a2556d2b
4 mainītis faili ar 85 papildinājumiem un 59 dzēšanām
  1. 18 15
      Makefile
  2. 44 30
      frozen.c
  3. 2 2
      frozen.h
  4. 21 12
      unit_test.c

+ 18 - 15
Makefile

@@ -1,24 +1,27 @@
-PROF = -fprofile-arcs -ftest-coverage -g -O0
-CFLAGS = -W -Wall -pedantic -O3 $(PROF) $(CFLAGS_EXTRA) -std=c99
-CXXFLAGS = -W -Wall -pedantic -O3 $(PROF) $(CFLAGS_EXTRA)
+PROF ?= -fprofile-arcs -ftest-coverage -g -O0
+CFLAGS ?= -W -Wall -pedantic -O3 $(PROF) $(CFLAGS_EXTRA) -std=c99
+CXXFLAGS ?= -W -Wall -pedantic -O3 $(PROF) $(CFLAGS_EXTRA)
+CLFLAGS ?= /DWIN32_LEAN_AND_MEAN /MD /O2 /TC /W2 /WX
 
 
-.PHONY: clean all
+RD ?= docker run -v $(CURDIR):$(CURDIR) -w $(CURDIR)
+GCC ?= $(RD) docker.cesanta.com/gcc
 
 
-all: c c++
+.PHONY: clean all vc98 vc2017 c c++
+
+all: ci-test
+ci-test: c c++ vc98 vc2017
 
 
 c: clean
 c: clean
-	rm -rf *.gc*
-	cc unit_test.c -o unit_test $(CFLAGS) && ./unit_test
-	cc -m32 unit_test.c -o unit_test $(CFLAGS) && ./unit_test
-	gcov -a unit_test.c
+	$(GCC) cc unit_test.c -o unit_test $(CFLAGS) && $(GCC) ./unit_test
+	$(GCC) gcov -a unit_test.c
 
 
 c++: clean
 c++: clean
-	rm -rf *.gc*
-	g++ unit_test.c -o unit_test $(CXXFLAGS) && ./unit_test
-	gcov -a unit_test.c
+	$(GCC) g++ unit_test.c -o unit_test $(CXXFLAGS) && $(GCC) ./unit_test
+	$(GCC) gcov -a unit_test.c
 
 
-w:
-	wine cl /DEBUG unit_test.c && wine unit_test.exe
+vc98 vc2017:
+	$(RD) docker.cesanta.com/$@ wine cl unit_test.c $(CLFLAGS) /[email protected]
+	$(RD) docker.cesanta.com/$@ wine [email protected] 
 
 
 clean:
 clean:
-	rm -rf *.gc* *.dSYM unit_test unit_test.exe
+	rm -rf *.gc* *.dSYM unit_test *.exe *.obj _CL_*

+ 44 - 30
frozen.c

@@ -35,6 +35,8 @@
 #endif
 #endif
 
 
 #ifdef _WIN32
 #ifdef _WIN32
+#undef snprintf
+#undef vsnprintf
 #define snprintf cs_win_snprintf
 #define snprintf cs_win_snprintf
 #define vsnprintf cs_win_vsnprintf
 #define vsnprintf cs_win_vsnprintf
 int cs_win_snprintf(char *str, size_t size, const char *format, ...);
 int cs_win_snprintf(char *str, size_t size, const char *format, ...);
@@ -47,26 +49,20 @@ typedef unsigned _int64 uint64_t;
 #endif
 #endif
 #define PRId64 "I64d"
 #define PRId64 "I64d"
 #define PRIu64 "I64u"
 #define PRIu64 "I64u"
-#if !defined(SIZE_T_FMT)
-#if _MSC_VER >= 1310
-#define SIZE_T_FMT "Iu"
-#else
-#define SIZE_T_FMT "u"
-#endif
-#endif
 #else /* _WIN32 */
 #else /* _WIN32 */
 /* <inttypes.h> wants this for C++ */
 /* <inttypes.h> wants this for C++ */
 #ifndef __STDC_FORMAT_MACROS
 #ifndef __STDC_FORMAT_MACROS
 #define __STDC_FORMAT_MACROS
 #define __STDC_FORMAT_MACROS
 #endif
 #endif
 #include <inttypes.h>
 #include <inttypes.h>
-#if !defined(SIZE_T_FMT)
-#define SIZE_T_FMT "zu"
-#endif
 #endif /* _WIN32 */
 #endif /* _WIN32 */
 
 
+#ifndef INT64_FMT
 #define INT64_FMT PRId64
 #define INT64_FMT PRId64
+#endif
+#ifndef UINT64_FMT
 #define UINT64_FMT PRIu64
 #define UINT64_FMT PRIu64
+#endif
 
 
 #ifndef va_copy
 #ifndef va_copy
 #define va_copy(x, y) x = y
 #define va_copy(x, y) x = y
@@ -502,7 +498,7 @@ static int b64rev(int c) {
   }
   }
 }
 }
 
 
-static uint8_t hexdec(const char *s) {
+static unsigned char hexdec(const char *s) {
 #define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W')
 #define HEXTOI(x) (x >= '0' && x <= '9' ? x - '0' : x - 'W')
   int a = tolower(*(const unsigned char *) s);
   int a = tolower(*(const unsigned char *) s);
   int b = tolower(*(const unsigned char *) (s + 1));
   int b = tolower(*(const unsigned char *) (s + 1));
@@ -566,7 +562,7 @@ int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
         skip += 2;
         skip += 2;
       } else if (fmt[1] == 'z' && fmt[2] == 'u') {
       } else if (fmt[1] == 'z' && fmt[2] == 'u') {
         size_t val = va_arg(ap, size_t);
         size_t val = va_arg(ap, size_t);
-        snprintf(buf, sizeof(buf), "%" SIZE_T_FMT, val);
+        snprintf(buf, sizeof(buf), "%lu", (unsigned long) val);
         len += out->printer(out, buf, strlen(buf));
         len += out->printer(out, buf, strlen(buf));
         skip += 1;
         skip += 1;
       } else if (fmt[1] == 'M') {
       } else if (fmt[1] == 'M') {
@@ -626,29 +622,47 @@ int json_vprintf(struct json_out *out, const char *fmt, va_list xap) {
          */
          */
 
 
         const char *end_of_format_specifier = "sdfFgGlhuIcx.*-0123456789";
         const char *end_of_format_specifier = "sdfFgGlhuIcx.*-0123456789";
-        size_t n = strspn(fmt + 1, end_of_format_specifier);
+        int n = strspn(fmt + 1, end_of_format_specifier);
         char *pbuf = buf;
         char *pbuf = buf;
-        size_t need_len;
+        int need_len, size = sizeof(buf);
         char fmt2[20];
         char fmt2[20];
-        va_list sub_ap;
-        strncpy(fmt2, fmt, n + 1 > sizeof(fmt2) ? sizeof(fmt2) : n + 1);
+        va_list ap_copy;
+        strncpy(fmt2, fmt,
+                n + 1 > (int) sizeof(fmt2) ? sizeof(fmt2) : (size_t) n + 1);
         fmt2[n + 1] = '\0';
         fmt2[n + 1] = '\0';
 
 
-        va_copy(sub_ap, ap);
-        need_len =
-            vsnprintf(buf, sizeof(buf), fmt2, sub_ap) + 1 /* null-term */;
-        /*
-         * TODO(lsm): Fix windows & eCos code path here. Their vsnprintf
-         * implementation returns -1 on overflow rather needed size.
-         */
-        if (need_len > sizeof(buf)) {
+        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`,
            * resulting string doesn't fit into a stack-allocated buffer `buf`,
            * so we need to allocate a new buffer from heap and use it
            * so we need to allocate a new buffer from heap and use it
            */
            */
-          pbuf = (char *) malloc(need_len);
-          va_copy(sub_ap, ap);
-          vsnprintf(pbuf, need_len, fmt2, sub_ap);
+          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;
         }
         }
 
 
         /*
         /*
@@ -1015,7 +1029,7 @@ int json_scanf(const char *str, int len, const char *fmt, ...) {
 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) WEAK;
 int json_vfprintf(const char *file_name, const char *fmt, va_list ap) {
 int json_vfprintf(const char *file_name, const char *fmt, va_list ap) {
   int res = -1;
   int res = -1;
-  FILE *fp = fopen(file_name, "w");
+  FILE *fp = fopen(file_name, "wb");
   if (fp != NULL) {
   if (fp != NULL) {
     struct json_out out = JSON_OUT_FILE(fp);
     struct json_out out = JSON_OUT_FILE(fp);
     res = json_vprintf(&out, fmt, ap);
     res = json_vprintf(&out, fmt, ap);
@@ -1263,13 +1277,13 @@ int json_prettify_file(const char *file_name) {
   int res = -1;
   int res = -1;
   char *s = json_fread(file_name);
   char *s = json_fread(file_name);
   FILE *fp;
   FILE *fp;
-  if (s != NULL && (fp = fopen(file_name, "w")) != NULL) {
+  if (s != NULL && (fp = fopen(file_name, "wb")) != NULL) {
     struct json_out out = JSON_OUT_FILE(fp);
     struct json_out out = JSON_OUT_FILE(fp);
     res = json_prettify(s, strlen(s), &out);
     res = json_prettify(s, strlen(s), &out);
     if (res < 0) {
     if (res < 0) {
       /* On error, restore the old content */
       /* On error, restore the old content */
       fclose(fp);
       fclose(fp);
-      fp = fopen(file_name, "w");
+      fp = fopen(file_name, "wb");
       fseek(fp, 0, SEEK_SET);
       fseek(fp, 0, SEEK_SET);
       fwrite(s, 1, strlen(s), fp);
       fwrite(s, 1, strlen(s), fp);
     } else {
     } else {

+ 2 - 2
frozen.h

@@ -28,8 +28,9 @@ extern "C" {
 #include <stddef.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdio.h>
 
 
-#ifdef _WIN32
+#if defined(_WIN32) && _MSC_VER < 1700
 typedef int bool;
 typedef int bool;
+enum { false = 0, true = 1 };
 #else
 #else
 #include <stdbool.h>
 #include <stdbool.h>
 #endif
 #endif
@@ -285,7 +286,6 @@ int json_prettify_file(const char *file_name);
 void *json_next_key(const char *s, int len, void *handle, const char *path,
 void *json_next_key(const char *s, int len, void *handle, const char *path,
                     struct json_token *key, struct json_token *val);
                     struct json_token *key, struct json_token *val);
 
 
-
 /*
 /*
  * Iterate over an array at given JSON `path`.
  * Iterate over an array at given JSON `path`.
  * Similar to `json_next_key`, but fills array index `idx` instead of `key`.
  * Similar to `json_next_key`, but fills array index `idx` instead of `key`.

+ 21 - 12
unit_test.c

@@ -28,7 +28,8 @@
 
 
 #include "frozen.c"
 #include "frozen.c"
 
 
-#include <stdbool.h>
+#include <float.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
@@ -170,7 +171,10 @@ static const char *test_json_printf(void) {
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
     const char *result = "12 42";
     const char *result = "12 42";
     size_t foo = 12;
     size_t foo = 12;
-    json_printf(&out, "%" SIZE_T_FMT " %d", foo, 42);
+    json_printf(&out,
+                "%lu"
+                " %d",
+                foo, 42);
     ASSERT(strcmp(buf, result) == 0);
     ASSERT(strcmp(buf, result) == 0);
   }
   }
 
 
@@ -273,9 +277,10 @@ static const char *test_json_printf(void) {
         "{\"foo\": "
         "{\"foo\": "
         "\"12345678901234567890123456789012345678901234567890123456789012345678"
         "\"12345678901234567890123456789012345678901234567890123456789012345678"
         "90123456789012345678901234567890\"}";
         "90123456789012345678901234567890\"}";
-    json_printf(&out, "{foo: %s}",
-                "\"123456789012345678901234567890123456789012345678901234567890"
-                "1234567890123456789012345678901234567890\"");
+    const char *s =
+        "\"123456789012345678901234567890123456789012345678901234567890"
+        "1234567890123456789012345678901234567890\"";
+    json_printf(&out, "{foo: %s}", s);
     ASSERT(strcmp(buf, result) == 0);
     ASSERT(strcmp(buf, result) == 0);
   }
   }
 
 
@@ -304,23 +309,26 @@ static const char *test_json_printf(void) {
 
 
   {
   {
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
+    const char *result = "\"YTI=\"";
     memset(buf, 0, sizeof(buf));
     memset(buf, 0, sizeof(buf));
     ASSERT(json_printf(&out, "%V", "a2", 2) > 0);
     ASSERT(json_printf(&out, "%V", "a2", 2) > 0);
-    ASSERT(strcmp(buf, "\"YTI=\"") == 0);
+    ASSERT(strcmp(buf, result) == 0);
   }
   }
 
 
   {
   {
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
+    const char *result = "\"ACABIAIgYWJj\"";
     memset(buf, 0, sizeof(buf));
     memset(buf, 0, sizeof(buf));
     ASSERT(json_printf(&out, "%V", "\x00 \x01 \x02 abc", 9) > 0);
     ASSERT(json_printf(&out, "%V", "\x00 \x01 \x02 abc", 9) > 0);
-    ASSERT(strcmp(buf, "\"ACABIAIgYWJj\"") == 0);
+    ASSERT(strcmp(buf, result) == 0);
   }
   }
 
 
   {
   {
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
     struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
+    const char *result = "\"002001200220616263\"";
     memset(buf, 0, sizeof(buf));
     memset(buf, 0, sizeof(buf));
     ASSERT(json_printf(&out, "%H", 9, "\x00 \x01 \x02 abc") > 0);
     ASSERT(json_printf(&out, "%H", 9, "\x00 \x01 \x02 abc") > 0);
-    ASSERT(strcmp(buf, "\"002001200220616263\"") == 0);
+    ASSERT(strcmp(buf, result) == 0);
   }
   }
 
 
   {
   {
@@ -344,7 +352,7 @@ static const char *test_json_printf(void) {
 
 
 static const char *test_system(void) {
 static const char *test_system(void) {
   char buf[2020];
   char buf[2020];
-  uint64_t u = 0xdeadbeeffee1dead;
+  uint64_t u = (uint64_t) 0xdeadbeeffee1dead;
   int64_t d = (int64_t) u;
   int64_t d = (int64_t) u;
   int res;
   int res;
 
 
@@ -616,7 +624,7 @@ static const char *test_scanf(void) {
 
 
   {
   {
     const char *str = "{ fa: 1, fb: 2.34, fc: 5.67 }";
     const char *str = "{ fa: 1, fb: 2.34, fc: 5.67 }";
-    float a = 1.0, b = 2.34;
+    float a = 1.0f, b = 2.34f;
     double c = 5.67;
     double c = 5.67;
     float fa = 0.0, fb = 0.0;
     float fa = 0.0, fb = 0.0;
     double fc = 0.0;
     double fc = 0.0;
@@ -624,7 +632,7 @@ static const char *test_scanf(void) {
                       &fc) == 3);
                       &fc) == 3);
     ASSERT(fa == a);
     ASSERT(fa == a);
     ASSERT(fb == b);
     ASSERT(fb == b);
-    ASSERT(fc == c);
+    ASSERT(fabs(fc - c) < FLT_EPSILON);
   }
   }
 
 
   return NULL;
   return NULL;
@@ -688,10 +696,11 @@ static int compare_file(const char *file_name, const char *s) {
 
 
 static const char *test_fprintf(void) {
 static const char *test_fprintf(void) {
   const char *fname = "a.json";
   const char *fname = "a.json";
+  const char *result = "{\"a\":123}\n";
   char *p;
   char *p;
   ASSERT(json_fprintf(fname, "{a:%d}", 123) > 0);
   ASSERT(json_fprintf(fname, "{a:%d}", 123) > 0);
   ASSERT((p = json_fread(fname)) != NULL);
   ASSERT((p = json_fread(fname)) != NULL);
-  ASSERT(strcmp(p, "{\"a\":123}\n") == 0);
+  ASSERT(strcmp(p, result) == 0);
   free(p);
   free(p);
   remove(fname);
   remove(fname);
   ASSERT(json_fread(fname) == NULL);
   ASSERT(json_fread(fname) == NULL);