Changes in / [6ae1056:820a2a7]


Ignore:
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • configure

    r6ae1056 r820a2a7  
    140140DESTDIR=
    141141LFLAGS=
    142 EFLAGS=-lm
     142EFLAGS=
    143143EOF
    144144
  • lib/json.c

    r6ae1056 r820a2a7  
    1 /* vim: set et ts=3 sw=3 sts=3 ft=c:
     1
     2/* vim: set et ts=3 sw=3 ft=c:
    23 *
    3  * Copyright (C) 2012, 2013, 2014 James McLaughlin et al.  All rights reserved.
     4 * Copyright (C) 2012 James McLaughlin et al.  All rights reserved.
    45 * https://github.com/udp/json-parser
    56 *
     
    2829 */
    2930
    30 #include <glib.h>
    31 
    3231#include "json.h"
    3332
     
    4443#endif
    4544
     45#include <glib.h>
     46#include <stdlib.h>
    4647#include <stdio.h>
    4748#include <string.h>
    4849#include <ctype.h>
    49 #include <math.h>
    5050
    5151typedef unsigned short json_uchar;
     
    5353static unsigned char hex_value (json_char c)
    5454{
    55    if (isdigit(c))
     55   if (c >= 'A' && c <= 'F')
     56      return (c - 'A') + 10;
     57
     58   if (c >= 'a' && c <= 'f')
     59      return (c - 'a') + 10;
     60
     61   if (c >= '0' && c <= '9')
    5662      return c - '0';
    5763
    58    switch (c) {
    59       case 'a': case 'A': return 0x0A;
    60       case 'b': case 'B': return 0x0B;
    61       case 'c': case 'C': return 0x0C;
    62       case 'd': case 'D': return 0x0D;
    63       case 'e': case 'E': return 0x0E;
    64       case 'f': case 'F': return 0x0F;
    65       default: return 0xFF;
    66    }
     64   return 0xFF;
    6765}
    6866
    6967typedef struct
    7068{
     69   json_settings settings;
     70   int first_pass;
     71
    7172   unsigned long used_memory;
    7273
     
    7475   unsigned long ulong_max;
    7576
    76    json_settings settings;
    77    int first_pass;
    78 
    7977} json_state;
    80 
    81 static void * default_alloc (size_t size, int zero, void * user_data)
    82 {
    83    return zero ? calloc (1, size) : malloc (size);
    84 }
    85 
    86 static void default_free (void * ptr, void * user_data)
    87 {
    88    free (ptr);
    89 }
    9078
    9179static void * json_alloc (json_state * state, unsigned long size, int zero)
    9280{
     81   void * mem;
     82
    9383   if ((state->ulong_max - state->used_memory) < size)
    9484      return 0;
     
    10090   }
    10191
    102    return state->settings.mem_alloc (size, zero, state->settings.user_data);
     92   if (! (mem = zero ? calloc (size, 1) : malloc (size)))
     93      return 0;
     94
     95   return mem;
    10396}
    10497
     
    127120            }
    128121
    129             value->u.array.length = 0;
    130122            break;
    131123
     
    142134            value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
    143135
    144             value->u.object.length = 0;
    145136            break;
    146137
     
    153144            }
    154145
    155             value->u.string.length = 0;
    156146            break;
    157147
     
    160150      };
    161151
     152      value->u.array.length = 0;
     153
    162154      return 1;
    163155   }
     
    192184   do { if (!state.first_pass) string [string_length] = b;  ++ string_length; } while (0);
    193185
    194 static const long
    195    flag_next             = 1 << 0,
    196    flag_reproc           = 1 << 1,
    197    flag_need_comma       = 1 << 2,
    198    flag_seek_value       = 1 << 3,
    199    flag_escaped          = 1 << 4,
    200    flag_string           = 1 << 5,
    201    flag_need_colon       = 1 << 6,
    202    flag_done             = 1 << 7,
    203    flag_num_negative     = 1 << 8,
    204    flag_num_zero         = 1 << 9,
    205    flag_num_e            = 1 << 10,
    206    flag_num_e_got_sign   = 1 << 11,
    207    flag_num_e_negative   = 1 << 12,
    208    flag_line_comment     = 1 << 13,
    209    flag_block_comment    = 1 << 14;
    210 
    211 json_value * json_parse_ex (json_settings * settings,
    212                             const json_char * json,
    213                             size_t length,
    214                             char * error_buf)
     186const static int
     187   flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8, flag_exponent = 16,
     188   flag_got_exponent_sign = 32, flag_escaped = 64, flag_string = 128, flag_need_colon = 256,
     189   flag_done = 512;
     190
     191json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf)
    215192{
    216    json_char error [json_error_max];
     193   json_char error [128];
    217194   unsigned int cur_line;
    218    const json_char * cur_line_begin, * i, * end;
     195   const json_char * cur_line_begin, * i;
    219196   json_value * top, * root, * alloc = 0;
    220    json_state state = { 0 };
    221    long flags;
    222    long num_digits = 0, num_e = 0;
    223    json_int_t num_fraction = 0;
    224 
    225    /* Skip UTF-8 BOM
    226     */
    227    if (length >= 3 && ((unsigned char) json [0]) == 0xEF
    228                    && ((unsigned char) json [1]) == 0xBB
    229                    && ((unsigned char) json [2]) == 0xBF)
    230    {
    231       json += 3;
    232       length -= 3;
    233    }
     197   json_state state;
     198   int flags;
    234199
    235200   error[0] = '\0';
    236    end = (json + length);
    237 
     201
     202   memset (&state, 0, sizeof (json_state));
    238203   memcpy (&state.settings, settings, sizeof (json_settings));
    239 
    240    if (!state.settings.mem_alloc)
    241       state.settings.mem_alloc = default_alloc;
    242 
    243    if (!state.settings.mem_free)
    244       state.settings.mem_free = default_free;
    245204
    246205   memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
     
    265224      for (i = json ;; ++ i)
    266225      {
    267          json_char b = (i == end ? 0 : *i);
    268          
     226         json_char b = *i;
     227
     228         if (flags & flag_done)
     229         {
     230            if (!b)
     231               break;
     232
     233            switch (b)
     234            {
     235               whitespace:
     236                  continue;
     237
     238               default:
     239                  sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
     240                  goto e_failed;
     241            };
     242         }
     243
    269244         if (flags & flag_string)
    270245         {
     
    290265                  case 'u':
    291266
    292                     if (end - i < 4 ||
    293                         (uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
     267                    if ((uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
    294268                          || (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
    295269                    {
     
    370344                           = (json_char *) top->_reserved.object_mem;
    371345
    372                         top->u.object.values [top->u.object.length].name_length
    373                            = string_length;
    374 
    375346                        (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
    376347                     }
     
    390361         }
    391362
    392          if (state.settings.settings & json_enable_comments)
    393          {
    394             if (flags & (flag_line_comment | flag_block_comment))
    395             {
    396                if (flags & flag_line_comment)
    397                {
    398                   if (b == '\r' || b == '\n' || !b)
    399                   {
    400                      flags &= ~ flag_line_comment;
    401                      -- i;  /* so null can be reproc'd */
    402                   }
    403 
    404                   continue;
    405                }
    406 
    407                if (flags & flag_block_comment)
    408                {
    409                   if (!b)
    410                   {  sprintf (error, "%d:%d: Unexpected EOF in block comment", cur_line, e_off);
    411                      goto e_failed;
    412                   }
    413 
    414                   if (b == '*' && i < (end - 1) && i [1] == '/')
    415                   {
    416                      flags &= ~ flag_block_comment;
    417                      ++ i;  /* skip closing sequence */
    418                   }
    419 
    420                   continue;
    421                }
    422             }
    423             else if (b == '/')
    424             {
    425                if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
    426                {
    427                   sprintf (error, "%d:%d: Comment not allowed here", cur_line, e_off);
    428                   goto e_failed;
    429                }
    430 
    431                if (++ i == end)
    432                {  sprintf (error, "%d:%d: EOF unexpected", cur_line, e_off);
    433                   goto e_failed;
    434                }
    435 
    436                switch (b = *i)
    437                {
    438                   case '/':
    439                      flags |= flag_line_comment;
    440                      continue;
    441 
    442                   case '*':
    443                      flags |= flag_block_comment;
    444                      continue;
    445 
    446                   default:
    447                      sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, b);
    448                      goto e_failed;
    449                };
    450             }
    451          }
    452 
    453          if (flags & flag_done)
    454          {
    455             if (!b)
    456                break;
    457 
    458             switch (b)
    459             {
    460                whitespace:
    461                   continue;
    462 
    463                default:
    464                   sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
    465                   goto e_failed;
    466             };
    467          }
    468 
    469363         if (flags & flag_seek_value)
    470364         {
     
    478372                  if (top->type == json_array)
    479373                     flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
    480                   else
     374                  else if (!state.settings.settings & json_relaxed_commas)
    481375                  {  sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off);
    482376                     goto e_failed;
     
    544438                     case 't':
    545439
    546                         if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
     440                        if (*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
    547441                           goto e_unknown_value;
    548442
     
    557451                     case 'f':
    558452
    559                         if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
     453                        if (*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
    560454                           goto e_unknown_value;
    561455
     
    568462                     case 'n':
    569463
    570                         if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
     464                        if (*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
    571465                           goto e_unknown_value;
    572466
     
    584478                              goto e_alloc_failure;
    585479
    586                            if (!state.first_pass)
    587                            {
    588                               while (isdigit (b) || b == '+' || b == '-'
    589                                         || b == 'e' || b == 'E' || b == '.')
    590                               {
    591                                  if ( (++ i) == end)
    592                                  {
    593                                     b = 0;
    594                                     break;
    595                                  }
    596 
    597                                  b = *i;
    598                               }
    599 
    600                               flags |= flag_next | flag_reproc;
    601                               break;
    602                            }
    603 
    604                            flags &= ~ (flag_num_negative | flag_num_e |
    605                                         flag_num_e_got_sign | flag_num_e_negative |
    606                                            flag_num_zero);
    607 
    608                            num_digits = 0;
    609                            num_fraction = 0;
    610                            num_e = 0;
    611 
    612                            if (b != '-')
    613                            {
    614                               flags |= flag_reproc;
    615                               break;
    616                            }
    617 
    618                            flags |= flag_num_negative;
    619                            continue;
     480                           flags &= ~ (flag_exponent | flag_got_exponent_sign);
     481
     482                           if (state.first_pass)
     483                              continue;
     484
     485                           if (top->type == json_double)
     486                              top->u.dbl = g_ascii_strtod (i, (json_char **) &i);
     487                           else
     488                              top->u.integer = g_ascii_strtoll (i, (json_char **) &i, 10);
     489
     490                           flags |= flag_next | flag_reproc;
    620491                        }
    621492                        else
     
    639510                  case '"':
    640511
    641                      if (flags & flag_need_comma)
     512                     if (flags & flag_need_comma && (!state.settings.settings & json_relaxed_commas))
    642513                     {
    643514                        sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off);
     
    677548
    678549               if (isdigit (b))
     550                  continue;
     551
     552               if (b == 'e' || b == 'E')
    679553               {
    680                   ++ num_digits;
    681 
    682                   if (top->type == json_integer || flags & flag_num_e)
     554                  if (!(flags & flag_exponent))
    683555                  {
    684                      if (! (flags & flag_num_e))
    685                      {
    686                         if (flags & flag_num_zero)
    687                         {  sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
    688                            goto e_failed;
    689                         }
    690 
    691                         if (num_digits == 1 && b == '0')
    692                            flags |= flag_num_zero;
    693                      }
    694                      else
    695                      {
    696                         flags |= flag_num_e_got_sign;
    697                         num_e = (num_e * 10) + (b - '0');
    698                         continue;
    699                      }
    700 
    701                      top->u.integer = (top->u.integer * 10) + (b - '0');
     556                     flags |= flag_exponent;
     557                     top->type = json_double;
     558
    702559                     continue;
    703560                  }
    704 
    705                   num_fraction = (num_fraction * 10) + (b - '0');
    706                   continue;
    707561               }
    708 
    709                if (b == '+' || b == '-')
     562               else if (b == '+' || b == '-')
    710563               {
    711                   if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
     564                  if (flags & flag_exponent && !(flags & flag_got_exponent_sign))
    712565                  {
    713                      flags |= flag_num_e_got_sign;
    714 
    715                      if (b == '-')
    716                         flags |= flag_num_e_negative;
    717 
     566                     flags |= flag_got_exponent_sign;
    718567                     continue;
    719568                  }
     
    721570               else if (b == '.' && top->type == json_integer)
    722571               {
    723                   if (!num_digits)
    724                   {  sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
    725                      goto e_failed;
    726                   }
    727 
    728572                  top->type = json_double;
    729                   top->u.dbl = (double) top->u.integer;
    730 
    731                   num_digits = 0;
    732573                  continue;
    733                }
    734 
    735                if (! (flags & flag_num_e))
    736                {
    737                   if (top->type == json_double)
    738                   {
    739                      if (!num_digits)
    740                      {  sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
    741                         goto e_failed;
    742                      }
    743 
    744                      top->u.dbl += ((double) num_fraction) / (pow (10, (double) num_digits));
    745                   }
    746 
    747                   if (b == 'e' || b == 'E')
    748                   {
    749                      flags |= flag_num_e;
    750 
    751                      if (top->type == json_integer)
    752                      {
    753                         top->type = json_double;
    754                         top->u.dbl = (double) top->u.integer;
    755                      }
    756 
    757                      num_digits = 0;
    758                      flags &= ~ flag_num_zero;
    759 
    760                      continue;
    761                   }
    762                }
    763                else
    764                {
    765                   if (!num_digits)
    766                   {  sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
    767                      goto e_failed;
    768                   }
    769 
    770                   top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
    771                }
    772 
    773                if (flags & flag_num_negative)
    774                {
    775                   if (top->type == json_integer)
    776                      top->u.integer = - top->u.integer;
    777                   else
    778                      top->u.dbl = - top->u.dbl;
    779574               }
    780575
     
    878673   {
    879674      top = alloc->_reserved.next_alloc;
    880       state.settings.mem_free (alloc, state.settings.user_data);
     675      free (alloc);
    881676      alloc = top;
    882677   }
    883678
    884679   if (!state.first_pass)
    885       json_value_free_ex (&state.settings, root);
     680      json_value_free (root);
    886681
    887682   return 0;
    888683}
    889684
    890 json_value * json_parse (const json_char * json, size_t length)
     685json_value * json_parse (const json_char * json)
    891686{
    892    json_settings settings = { 0 };
    893    return json_parse_ex (&settings, json, length, 0);
     687   json_settings settings;
     688   memset (&settings, 0, sizeof (json_settings));
     689
     690   return json_parse_ex (&settings, json, 0);
    894691}
    895692
    896 void json_value_free_ex (json_settings * settings, json_value * value)
     693void json_value_free (json_value * value)
    897694{
    898695   json_value * cur_value;
     
    911708            if (!value->u.array.length)
    912709            {
    913                settings->mem_free (value->u.array.values, settings->user_data);
     710               free (value->u.array.values);
    914711               break;
    915712            }
     
    922719            if (!value->u.object.length)
    923720            {
    924                settings->mem_free (value->u.object.values, settings->user_data);
     721               free (value->u.object.values);
    925722               break;
    926723            }
     
    931728         case json_string:
    932729
    933             settings->mem_free (value->u.string.ptr, settings->user_data);
     730            free (value->u.string.ptr);
    934731            break;
    935732
     
    940737      cur_value = value;
    941738      value = value->parent;
    942       settings->mem_free (cur_value, settings->user_data);
     739      free (cur_value);
    943740   }
    944741}
    945742
    946 void json_value_free (json_value * value)
    947 {
    948    json_settings settings = { 0 };
    949    settings.mem_free = default_free;
    950    json_value_free_ex (&settings, value);
    951 }
    952 
     743
  • lib/json.h

    r6ae1056 r820a2a7  
    11
    2 /* vim: set et ts=3 sw=3 sts=3 ft=c:
     2/* vim: set et ts=3 sw=3 ft=c:
    33 *
    4  * Copyright (C) 2012, 2013, 2014 James McLaughlin et al.  All rights reserved.
     4 * Copyright (C) 2012 James McLaughlin et al.  All rights reserved.
    55 * https://github.com/udp/json-parser
    66 *
     
    3636#endif
    3737
    38 #ifndef json_int_t
    39    #ifndef _MSC_VER
    40       #include <inttypes.h>
    41       #define json_int_t int64_t
    42    #else
    43       #define json_int_t __int64
    44    #endif
    45 #endif
    46 
    47 #include <stdlib.h>
    48 
    4938#ifdef __cplusplus
    5039
     
    6150   int settings;
    6251
    63    /* Custom allocator support (leave null to use malloc/free)
    64     */
    65 
    66    void * (* mem_alloc) (size_t, int zero, void * user_data);
    67    void (* mem_free) (void *, void * user_data);
    68 
    69    void * user_data;  /* will be passed to mem_alloc and mem_free */
    70 
    7152} json_settings;
    7253
    73 #define json_enable_comments  0x01
     54#define json_relaxed_commas 1
    7455
    7556typedef enum
     
    9778   {
    9879      int boolean;
    99       json_int_t integer;
     80      long long integer;
    10081      double dbl;
    10182
     
    11495         {
    11596            json_char * name;
    116             unsigned int name_length;
    117 
    11897            struct _json_value * value;
    11998
    12099         } * values;
    121 
    122          #if defined(__cplusplus) && __cplusplus >= 201103L
    123          decltype(values) begin () const
    124          {  return values;
    125          }
    126          decltype(values) end () const
    127          {  return values + length;
    128          }
    129          #endif
    130100
    131101      } object;
     
    135105         unsigned int length;
    136106         struct _json_value ** values;
    137 
    138          #if defined(__cplusplus) && __cplusplus >= 201103L
    139          decltype(values) begin () const
    140          {  return values;
    141          }
    142          decltype(values) end () const
    143          {  return values + length;
    144          }
    145          #endif
    146107
    147108      } array;
     
    202163         }
    203164
    204          inline operator json_int_t () const
    205          { 
    206             switch (type)
    207             {
    208                case json_integer:
    209                   return u.integer;
    210 
    211                case json_double:
    212                   return (json_int_t) u.dbl;
    213 
    214                default:
    215                   return 0;
    216             };
     165         inline operator long () const
     166         {  return u.integer;
    217167         }
    218168
    219169         inline operator bool () const
    220          { 
    221             if (type != json_boolean)
    222                return false;
    223 
    224             return u.boolean != 0;
    225          }
    226 
    227          inline operator double () const
    228          { 
    229             switch (type)
    230             {
    231                case json_integer:
    232                   return (double) u.integer;
    233 
    234                case json_double:
    235                   return u.dbl;
    236 
    237                default:
    238                   return 0;
    239             };
     170         {  return u.boolean != 0;
    240171         }
    241172
     
    244175} json_value;
    245176
    246 json_value * json_parse (const json_char * json,
    247                          size_t length);
     177json_value * json_parse
     178   (const json_char * json);
    248179
    249 #define json_error_max 128
    250 json_value * json_parse_ex (json_settings * settings,
    251                             const json_char * json,
    252                             size_t length,
    253                             char * error);
     180json_value * json_parse_ex
     181   (json_settings * settings, const json_char * json, char * error);
    254182
    255183void json_value_free (json_value *);
    256 
    257 
    258 /* Not usually necessary, unless you used a custom mem_alloc and now want to
    259  * use a custom mem_free.
    260  */
    261 void json_value_free_ex (json_settings * settings,
    262                          json_value *);
    263184
    264185
  • lib/oauth2.c

    r6ae1056 r820a2a7  
    154154                              strstr( content_type, "text/javascript" ) ) )
    155155        {
    156                 json_value *js = json_parse( req->reply_body, req->body_size );
     156                json_value *js = json_parse( req->reply_body );
    157157                if( js && js->type == json_object )
    158158                {
  • protocols/twitter/twitter_lib.c

    r6ae1056 r820a2a7  
    164164
    165165        if (req->body_size > 0) {
    166                 root = json_parse(req->reply_body, req->body_size);
     166                root = json_parse(req->reply_body);
    167167                err = json_o_get(root, "errors");
    168168                if (err && err->type == json_array && (err = err->u.array.values[0]) &&
     
    220220        }
    221221
    222         if ((ret = json_parse(req->reply_body, req->body_size)) == NULL) {
     222        if ((ret = json_parse(req->reply_body)) == NULL) {
    223223                imcb_error(ic, "Could not retrieve %s: %s",
    224224                           path, "XML parse error");
     
    263263               
    264264                txl->list = g_slist_prepend(txl->list,
    265                         g_strdup_printf("%" PRIu64, c->u.array.values[i]->u.integer));
     265                        g_strdup_printf("%lld", c->u.array.values[i]->u.integer));
    266266        }
    267267       
     
    773773                req->reply_body[len] = '\0';
    774774               
    775                 if ((parsed = json_parse(req->reply_body, req->body_size))) {
     775                if ((parsed = json_parse(req->reply_body))) {
    776776                        twitter_stream_handle_object(ic, parsed);
    777777                }
Note: See TracChangeset for help on using the changeset viewer.