00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ks_config.h"
00023 #include "ks_bparse.h"
00024 #include "ks_assoc.h"
00025 #include "ks_array.h"
00026 #include "ks_string.h"
00027 #include "ks_number.h"
00028
00029 #ifdef HAVE_STDLIB_H
00030 #include <stdlib.h>
00031 #endif
00032
00033 #ifdef HAVE_CTYPE_H
00034 #include <ctype.h>
00035 #endif
00036
00037 #ifdef HAVE_STDIO_H
00038 #include <stdio.h>
00039 #endif
00040
00060 static long
00061 ks_strtol(const char **datap, const char *endp, char stop)
00062 {
00063 const char *cp = *datap;
00064 long value = 0;
00065 char invert = 0;
00066
00067 if (cp < endp && *cp == '-') {
00068 cp++;
00069 invert = 1;
00070 }
00071
00072 while (cp < endp) {
00073 char c = *cp++;
00074 if (c == stop)
00075 break;
00076 if (!isdigit(c)) {
00077
00078 ks_error("Invalid character %c in number %8.8s",
00079 c, *datap);
00080 break;
00081 }
00082
00083 value = (value * 10) + (c - '0');
00084 }
00085 *datap = cp;
00086
00087 if (invert)
00088 value = 0 - value;
00089
00090 return value;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 static ks_base_t *
00102 ks_bparse_recursive(const char **datap, const char *endp)
00103 {
00104 ks_array_t *a;
00105 ks_assoc_t *s;
00106 ks_string_t *r;
00107 ks_base_t *b;
00108 const char *k;
00109 const char *cp = *datap;
00110 long l;
00111
00112 if (cp == endp)
00113 return NULL;
00114 switch (*cp++) {
00115 case '0': case '1': case '2': case '3': case '4':
00116 case '5': case '6': case '7': case '8': case '9':
00117 cp--;
00118 l = ks_strtol(&cp, endp, ':');
00119 if (cp + l > endp) {
00120 ks_error("String length %ld longer than "
00121 "data length %d", l, endp - cp);
00122 return NULL;
00123 }
00124 r = ks_string_new(cp, l);
00125 *datap = cp + l;
00126 return (ks_base_t *)r;
00127 case 'i':
00128 l = ks_strtol(&cp, endp, 'e');
00129 *datap = cp;
00130 return (ks_base_t *)ks_number_new(l);
00131 case 'l':
00132 a = ks_array_new();
00133 *datap = cp;
00134 while (**datap != 'e') {
00135 b = ks_bparse_recursive(datap, endp);
00136 if (b == NULL) {
00137 ks_array_free(a);
00138 return NULL;
00139 }
00140 ks_array_add(a, b);
00141 }
00142 (*datap)++;
00143 return (ks_base_t *)a;
00144 case 'd':
00145 s = ks_assoc_new();
00146 *datap = cp;
00147 while (**datap != 'e') {
00148 if (!isdigit(**datap)) {
00149
00150 ks_error("Key %8.8s not a string", *datap);
00151 ks_assoc_free(s);
00152 return NULL;
00153 }
00154
00155 l = ks_strtol(datap, endp, ':');
00156 k = *datap;
00157 *datap += l;
00158
00159 b = ks_bparse_recursive(datap, endp);
00160 if (b == NULL) {
00161 ks_assoc_free(s);
00162 return NULL;
00163 }
00164
00165 ks_assoc_put(s, k, l, b);
00166 }
00167 (*datap)++;
00168 return (ks_base_t *)s;
00169 case 'e':
00170
00171
00172
00173
00174
00175
00176
00177
00178 default:
00179
00180 ks_error("Value %8.8s not valid", *datap);
00181 break;
00182 }
00183
00184 return NULL;
00185 }
00186
00200 ks_base_t *
00201 ks_bparse(const char *data, int len)
00202 {
00203 const char *endp = data + len;
00204 return ks_bparse_recursive(&data, endp);
00205 }