Browse Source

jim: remove Jim_Error mechanism

rexim 1 month ago
parent
commit
ec7fe1d28a
4 changed files with 138 additions and 222 deletions
  1. 0 6
      README.md
  2. 0 6
      examples/01_from_readme.c
  3. 6 2
      jim1.h
  4. 132 208
      jim2.h

+ 0 - 6
README.md

@@ -52,12 +52,6 @@ int main()
         jim_array_end(&jim);
     jim_object_end(&jim);
 
-    if (jim.error != JIM_OK) {
-        fprintf(stderr, "ERROR: could not serialize json properly: %s\n",
-                jim_error_string(jim.error));
-        return -1;
-    }
-
     fwrite(jim.sink, jim.sink_count, 1, stdout);
 
     return 0;

+ 0 - 6
examples/01_from_readme.c

@@ -43,12 +43,6 @@ int main()
         jim_array_end(&jim);
     jim_object_end(&jim);
 
-    if (jim.error != JIM_OK) {
-        fprintf(stderr, "ERROR: could not serialize json properly: %s\n",
-                jim_error_string(jim.error));
-        return -1;
-    }
-
     fwrite(jim.sink, jim.sink_count, 1, stdout);
 
     return 0;

+ 6 - 2
jim1.h

@@ -1,7 +1,11 @@
 // Jim 1.0
 //
-// This is a legacy version of jim which uses fixed array for scopes and Jim_Sink/Jim_Write
-// interface to abstract away the IO. Not actively supported. Please use Jim 2.0 for new projects.
+// This is a legacy version of jim which uses
+// - Fixed array for scopes,
+// - Jim_Sink/Jim_Write interface to abstract away the IO,
+// - Jim_Error mechanism for indicating IO errors and/or invalid usage of the API.
+//
+// Not actively supported. Please use Jim 2.0 for new projects. This code is preserved because 2.0 is not backward compatible with 1.0.
 #ifndef JIM_H_
 #define JIM_H_
 

+ 132 - 208
jim2.h

@@ -1,6 +1,9 @@
 // Jim 2.0
 //
-// Main difference from Jim 1.0 is using dynamic arrays for scopes and string builder for sink.
+// Current version of Jim. Main differences from Jim 1.0 are
+// - Using Dynamic Arrays for scopes allowing them to be arbitrarily nested,
+// - Collecting the output into a sink which is a String Builder now, delegating all the IO hustle to the user of the library,
+// - Lack of Jim_Error mechanism, which dealt with IO errors and invalid usage of the API. Since we don't deal with IO anymore we have no IO errors. And invalid usage of the API is simply assert()-ed.
 
 #ifndef JIM_H_
 #define JIM_H_
@@ -13,15 +16,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-typedef enum {
-    JIM_OK = 0,
-    JIM_SCOPES_UNDERFLOW,
-    JIM_OUT_OF_SCOPE_KEY,
-    JIM_DOUBLE_KEY
-} Jim_Error;
-
-const char *jim_error_string(Jim_Error error);
-
 typedef enum {
     JIM_ARRAY_SCOPE,
     JIM_OBJECT_SCOPE,
@@ -34,7 +28,6 @@ typedef struct {
 } Jim_Scope;
 
 typedef struct {
-    Jim_Error error;
     char *sink;
     size_t sink_count;
     size_t sink_capacity;
@@ -67,61 +60,47 @@ void jim_object_end(Jim *jim);
 
 static void jim_scope_push(Jim *jim, Jim_Scope_Kind kind)
 {
-    if (jim->error == JIM_OK) {
-        if (jim->scopes_count >= jim->scopes_capacity) {
-            if (jim->scopes_capacity == 0) jim->scopes_capacity = JIM_SCOPES_CAPACITY;
-            else jim->scopes_capacity *= 2;
-            jim->scopes = realloc(jim->scopes, sizeof(*jim->scopes)*jim->scopes_capacity);
-            assert(jim->scopes);
-        }
-        jim->scopes[jim->scopes_count].kind = kind;
-        jim->scopes[jim->scopes_count].tail = 0;
-        jim->scopes[jim->scopes_count].key = 0;
-        jim->scopes_count += 1;
+    if (jim->scopes_count >= jim->scopes_capacity) {
+        if (jim->scopes_capacity == 0) jim->scopes_capacity = JIM_SCOPES_CAPACITY;
+        else jim->scopes_capacity *= 2;
+        jim->scopes = realloc(jim->scopes, sizeof(*jim->scopes)*jim->scopes_capacity);
+        assert(jim->scopes);
     }
+    jim->scopes[jim->scopes_count].kind = kind;
+    jim->scopes[jim->scopes_count].tail = 0;
+    jim->scopes[jim->scopes_count].key = 0;
+    jim->scopes_count += 1;
 }
 
 static void jim_scope_pop(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        if (jim->scopes_count > 0) {
-            jim->scopes_count--;
-        } else {
-            jim->error = JIM_SCOPES_UNDERFLOW;
-        }
-    }
+    assert(jim->scopes_count > 0);
+    jim->scopes_count--;
 }
 
 static Jim_Scope *jim_current_scope(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        if (jim->scopes_count > 0) {
-            return &jim->scopes[jim->scopes_count - 1];
-        }
+    if (jim->scopes_count > 0) {
+        return &jim->scopes[jim->scopes_count - 1];
     }
-
     return NULL;
 }
 
 static void jim_write(Jim *jim, const char *buffer, size_t size)
 {
-    if (jim->error == JIM_OK) {
-        while (jim->sink_count + size >= jim->sink_capacity) {
-            // TODO: rename JIM_SCOPES_CAPACITY to something else since it's used by both sink and scopes
-            if (jim->sink_capacity == 0) jim->sink_capacity = JIM_SCOPES_CAPACITY;
-            else jim->sink_capacity *= 2;
-            jim->sink = realloc(jim->sink, sizeof(*jim->sink)*jim->sink_capacity);
-        }
-        memcpy(jim->sink + jim->sink_count, buffer, size);
-        jim->sink_count += size;
+    while (jim->sink_count + size >= jim->sink_capacity) {
+        // TODO: rename JIM_SCOPES_CAPACITY to something else since it's used by both sink and scopes
+        if (jim->sink_capacity == 0) jim->sink_capacity = JIM_SCOPES_CAPACITY;
+        else jim->sink_capacity *= 2;
+        jim->sink = realloc(jim->sink, sizeof(*jim->sink)*jim->sink_capacity);
     }
+    memcpy(jim->sink + jim->sink_count, buffer, size);
+    jim->sink_count += size;
 }
 
 static void jim_write_cstr(Jim *jim, const char *cstr)
 {
-    if (jim->error == JIM_OK) {
-        jim_write(jim, cstr, strlen(cstr));
-    }
+    jim_write(jim, cstr, strlen(cstr));
 }
 
 static int jim_get_utf8_char_len(unsigned char ch)
@@ -139,102 +118,72 @@ static int jim_get_utf8_char_len(unsigned char ch)
 
 void jim_element_begin(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        Jim_Scope *scope = jim_current_scope(jim);
-        if (scope && scope->tail && !scope->key) {
-            jim_write_cstr(jim, ",");
-        }
+    Jim_Scope *scope = jim_current_scope(jim);
+    if (scope && scope->tail && !scope->key) {
+        jim_write_cstr(jim, ",");
     }
 }
 
 void jim_element_end(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        Jim_Scope *scope = jim_current_scope(jim);
-        if (scope) {
-            scope->tail = 1;
-            scope->key = 0;
-        }
-    }
-}
-
-const char *jim_error_string(Jim_Error error)
-{
-    // TODO(#1): error strings are not particularly useful
-    switch (error) {
-    case JIM_OK:
-        return "There is no error. The developer of this software just had a case of \"Task failed successfully\" https://i.imgur.com/Bdb3rkq.jpg - Please contact the developer and tell them that they are very lazy for not checking errors properly.";
-    case JIM_SCOPES_UNDERFLOW:
-        return "Stack of Scopes Underflow";
-    case JIM_OUT_OF_SCOPE_KEY:
-        return "Out of Scope key";
-    case JIM_DOUBLE_KEY:
-        return "Tried to set the member key twice";
-    default:
-        return NULL;
+    Jim_Scope *scope = jim_current_scope(jim);
+    if (scope) {
+        scope->tail = 1;
+        scope->key = 0;
     }
 }
 
 void jim_null(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        jim_write_cstr(jim, "null");
-        jim_element_end(jim);
-    }
+    jim_element_begin(jim);
+    jim_write_cstr(jim, "null");
+    jim_element_end(jim);
 }
 
 void jim_bool(Jim *jim, int boolean)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        if (boolean) {
-            jim_write_cstr(jim, "true");
-        } else {
-            jim_write_cstr(jim, "false");
-        }
-        jim_element_end(jim);
+    jim_element_begin(jim);
+    if (boolean) {
+        jim_write_cstr(jim, "true");
+    } else {
+        jim_write_cstr(jim, "false");
     }
+    jim_element_end(jim);
 }
 
 static void jim_integer_no_element(Jim *jim, long long int x)
 {
-    if (jim->error == JIM_OK) {
-        if (x < 0) {
-            jim_write_cstr(jim, "-");
-            x = -x;
-        }
-
-        if (x == 0) {
-            jim_write_cstr(jim, "0");
-        } else {
-            char buffer[64];
-            size_t count = 0;
+    if (x < 0) {
+        jim_write_cstr(jim, "-");
+        x = -x;
+    }
 
-            while (x > 0) {
-                buffer[count++] = (x % 10) + '0';
-                x /= 10;
-            }
+    if (x == 0) {
+        jim_write_cstr(jim, "0");
+    } else {
+        char buffer[64];
+        size_t count = 0;
 
-            for (size_t i = 0; i < count / 2; ++i) {
-                char t = buffer[i];
-                buffer[i] = buffer[count - i - 1];
-                buffer[count - i - 1] = t;
-            }
+        while (x > 0) {
+            buffer[count++] = (x % 10) + '0';
+            x /= 10;
+        }
 
-            jim_write(jim, buffer, count);
+        for (size_t i = 0; i < count / 2; ++i) {
+            char t = buffer[i];
+            buffer[i] = buffer[count - i - 1];
+            buffer[count - i - 1] = t;
         }
 
+        jim_write(jim, buffer, count);
     }
 }
 
 void jim_integer(Jim *jim, long long int x)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        jim_integer_no_element(jim, x);
-        jim_element_end(jim);
-    }
+    jim_element_begin(jim);
+    jim_integer_no_element(jim, x);
+    jim_element_end(jim);
 }
 
 static int is_nan_or_inf(double x)
@@ -245,141 +194,116 @@ static int is_nan_or_inf(double x)
 
 void jim_float(Jim *jim, double x, int precision)
 {
-    if (jim->error == JIM_OK) {
-        if (is_nan_or_inf(x)) {
-            jim_null(jim);
-        } else {
-            jim_element_begin(jim);
-
-            jim_integer_no_element(jim, (long long int) x);
-            x -= (double) (long long int) x;
-            while (precision-- > 0) {
-                x *= 10.0;
-            }
-            jim_write_cstr(jim, ".");
-
-            long long int y = (long long int) x;
-            if (y < 0) {
-                y = -y;
-            }
-            jim_integer_no_element(jim, y);
-
-            jim_element_end(jim);
+    if (is_nan_or_inf(x)) {
+        jim_null(jim);
+    } else {
+        jim_element_begin(jim);
+
+        jim_integer_no_element(jim, (long long int) x);
+        x -= (double) (long long int) x;
+        while (precision-- > 0) {
+            x *= 10.0;
         }
+        jim_write_cstr(jim, ".");
+
+        long long int y = (long long int) x;
+        if (y < 0) {
+            y = -y;
+        }
+        jim_integer_no_element(jim, y);
+
+        jim_element_end(jim);
     }
 }
 
 static void jim_string_sized_no_element(Jim *jim, const char *str, size_t size)
 {
-    if (jim->error == JIM_OK) {
-        const char *hex_digits = "0123456789abcdef";
-        const char *specials = "btnvfr";
-        const char *p = str;
-        size_t len = size;
-
-        jim_write_cstr(jim, "\"");
-        size_t cl;
-        for (size_t i = 0; i < len; i++) {
-            unsigned char ch = ((unsigned char *) p)[i];
-            if (ch == '"' || ch == '\\') {
-                jim_write(jim, "\\", 1);
-                jim_write(jim, p + i, 1);
-            } else if (ch >= '\b' && ch <= '\r') {
-                jim_write(jim, "\\", 1);
-                jim_write(jim, &specials[ch - '\b'], 1);
-            } else if (0x20 <= ch && ch <= 0x7F) { // is printable
-                jim_write(jim, p + i, 1);
-            } else if ((cl = jim_get_utf8_char_len(ch)) == 1) {
-                jim_write(jim, "\\u00", 4);
-                jim_write(jim, &hex_digits[(ch >> 4) % 0xf], 1);
-                jim_write(jim, &hex_digits[ch % 0xf], 1);
-            } else {
-                jim_write(jim, p + i, cl);
-                i += cl - 1;
-            }
-        }
-
-        jim_write_cstr(jim, "\"");
+    const char *hex_digits = "0123456789abcdef";
+    const char *specials = "btnvfr";
+    const char *p = str;
+    size_t len = size;
+
+    jim_write_cstr(jim, "\"");
+    size_t cl;
+    for (size_t i = 0; i < len; i++) {
+        unsigned char ch = ((unsigned char *) p)[i];
+        if (ch == '"' || ch == '\\') {
+            jim_write(jim, "\\", 1);
+            jim_write(jim, p + i, 1);
+        } else if (ch >= '\b' && ch <= '\r') {
+            jim_write(jim, "\\", 1);
+            jim_write(jim, &specials[ch - '\b'], 1);
+        } else if (0x20 <= ch && ch <= 0x7F) { // is printable
+        jim_write(jim, p + i, 1);
+    } else if ((cl = jim_get_utf8_char_len(ch)) == 1) {
+        jim_write(jim, "\\u00", 4);
+        jim_write(jim, &hex_digits[(ch >> 4) % 0xf], 1);
+        jim_write(jim, &hex_digits[ch % 0xf], 1);
+    } else {
+        jim_write(jim, p + i, cl);
+        i += cl - 1;
     }
 }
 
+jim_write_cstr(jim, "\"");
+}
+
 void jim_string_sized(Jim *jim, const char *str, size_t size)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        jim_string_sized_no_element(jim, str, size);
-        jim_element_end(jim);
-    }
+    jim_element_begin(jim);
+    jim_string_sized_no_element(jim, str, size);
+    jim_element_end(jim);
 }
 
 void jim_string(Jim *jim, const char *str)
 {
-    if (jim->error == JIM_OK) {
-        jim_string_sized(jim, str, strlen(str));
-    }
+    jim_string_sized(jim, str, strlen(str));
 }
 
 void jim_array_begin(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        jim_write_cstr(jim, "[");
-        jim_scope_push(jim, JIM_ARRAY_SCOPE);
-    }
+    jim_element_begin(jim);
+    jim_write_cstr(jim, "[");
+    jim_scope_push(jim, JIM_ARRAY_SCOPE);
 }
 
 
 void jim_array_end(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        jim_write_cstr(jim, "]");
-        jim_scope_pop(jim);
-        jim_element_end(jim);
-    }
+    jim_write_cstr(jim, "]");
+    jim_scope_pop(jim);
+    jim_element_end(jim);
 }
 
 void jim_object_begin(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        jim_write_cstr(jim, "{");
-        jim_scope_push(jim, JIM_OBJECT_SCOPE);
-    }
+    jim_element_begin(jim);
+    jim_write_cstr(jim, "{");
+    jim_scope_push(jim, JIM_OBJECT_SCOPE);
 }
 
 void jim_member_key(Jim *jim, const char *str)
 {
-    if (jim->error == JIM_OK) {
-        jim_member_key_sized(jim, str, strlen(str));
-    }
+    jim_member_key_sized(jim, str, strlen(str));
 }
 
 void jim_member_key_sized(Jim *jim, const char *str, size_t size)
 {
-    if (jim->error == JIM_OK) {
-        jim_element_begin(jim);
-        Jim_Scope *scope = jim_current_scope(jim);
-        if (scope && scope->kind == JIM_OBJECT_SCOPE) {
-            if (!scope->key) {
-                jim_string_sized_no_element(jim, str, size);
-                jim_write_cstr(jim, ":");
-                scope->key = 1;
-            } else {
-                jim->error = JIM_DOUBLE_KEY;
-            }
-        } else {
-            jim->error = JIM_OUT_OF_SCOPE_KEY;
-        }
-    }
+    jim_element_begin(jim);
+    Jim_Scope *scope = jim_current_scope(jim);
+    assert(scope);
+    assert(scope->kind == JIM_OBJECT_SCOPE);
+    assert(!scope->key);
+    jim_string_sized_no_element(jim, str, size);
+    jim_write_cstr(jim, ":");
+    scope->key = 1;
 }
 
 void jim_object_end(Jim *jim)
 {
-    if (jim->error == JIM_OK) {
-        jim_write_cstr(jim, "}");
-        jim_scope_pop(jim);
-        jim_element_end(jim);
-    }
+    jim_write_cstr(jim, "}");
+    jim_scope_pop(jim);
+    jim_element_end(jim);
 }
 
 #endif // JIM_IMPLEMENTATION