/* * call-seq: initialize_copy(orig) * * Initializes this object from orig if it to be duplicated/cloned and returns * it. */ static VALUE cState_init_copy(VALUE obj, VALUE orig) { JSON_Generator_State *objState, *origState; Data_Get_Struct(obj, JSON_Generator_State, objState); Data_Get_Struct(orig, JSON_Generator_State, origState); if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); MEMCPY(objState, origState, JSON_Generator_State, 1); objState->indent = fstrndup(origState->indent, origState->indent_len); objState->space = fstrndup(origState->space, origState->space_len); objState->space_before = fstrndup(origState->space_before, origState->space_before_len); objState->object_nl = fstrndup(origState->object_nl, origState->object_nl_len); objState->array_nl = fstrndup(origState->array_nl, origState->array_nl_len); if (origState->array_delim) objState->array_delim = fbuffer_dup(origState->array_delim); if (origState->object_delim) objState->object_delim = fbuffer_dup(origState->object_delim); if (origState->object_delim2) objState->object_delim2 = fbuffer_dup(origState->object_delim2); return obj; }
/* * call-seq: array_nl=(array_nl) * * This string is put at the end of a line that holds a JSON array. */ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl) { unsigned long len; GET_STATE(self); Check_Type(array_nl, T_STRING); len = RSTRING_LEN(array_nl); if (len == 0) { if (state->array_nl) { ruby_xfree(state->array_nl); state->array_nl = NULL; } } else { if (state->array_nl) ruby_xfree(state->array_nl); state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); state->array_nl_len = len; } return Qnil; }
/* * call-seq: space_before=(space_before) * * Sets the string that is used to insert a space before the ':' in JSON objects. */ static VALUE cState_space_before_set(VALUE self, VALUE space_before) { unsigned long len; GET_STATE(self); Check_Type(space_before, T_STRING); len = RSTRING_LEN(space_before); if (len == 0) { if (state->space_before) { ruby_xfree(state->space_before); state->space_before = NULL; state->space_before_len = 0; } } else { if (state->space_before) ruby_xfree(state->space_before); state->space_before = fstrndup(RSTRING_PTR(space_before), len); state->space_before_len = len; } return Qnil; }
/* * call-seq: indent=(indent) * * Sets the string that is used to indent levels in the JSON text. */ static VALUE cState_indent_set(VALUE self, VALUE indent) { unsigned long len; GET_STATE(self); Check_Type(indent, T_STRING); len = RSTRING_LEN(indent); if (len == 0) { if (state->indent) { ruby_xfree(state->indent); state->indent = NULL; state->indent_len = 0; } } else { if (state->indent) ruby_xfree(state->indent); state->indent = fstrndup(RSTRING_PTR(indent), len); state->indent_len = len; } return Qnil; }
/* * call-seq: configure(opts) * * Configure this State instance with the Hash _opts_, and return * itself. */ static VALUE cState_configure(VALUE self, VALUE opts) { VALUE tmp; GET_STATE(self); tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h"); if (NIL_P(tmp)) { rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash"); } opts = tmp; tmp = rb_hash_aref(opts, ID2SYM(i_indent)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->indent = fstrndup(RSTRING_PTR(tmp), len); state->indent_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->space = fstrndup(RSTRING_PTR(tmp), len); state->space_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space_before)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->space_before = fstrndup(RSTRING_PTR(tmp), len); state->space_before_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_array_nl)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->array_nl = fstrndup(RSTRING_PTR(tmp), len); state->array_nl_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_object_nl)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->object_nl = fstrndup(RSTRING_PTR(tmp), len); state->object_nl_len = len; } tmp = ID2SYM(i_max_nesting); state->max_nesting = 19; if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { Check_Type(max_nesting, T_FIXNUM); state->max_nesting = FIX2LONG(max_nesting); } else { state->max_nesting = 0; } } tmp = ID2SYM(i_depth); state->depth = 0; if (option_given_p(opts, tmp)) { VALUE depth = rb_hash_aref(opts, tmp); if (RTEST(depth)) { Check_Type(depth, T_FIXNUM); state->depth = FIX2LONG(depth); } else { state->depth = 0; } } tmp = ID2SYM(i_buffer_initial_length); if (option_given_p(opts, tmp)) { VALUE buffer_initial_length = rb_hash_aref(opts, tmp); if (RTEST(buffer_initial_length)) { long initial_length; Check_Type(buffer_initial_length, T_FIXNUM); initial_length = FIX2LONG(buffer_initial_length); if (initial_length > 0) state->buffer_initial_length = initial_length; } } tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan)); state->allow_nan = RTEST(tmp); tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only)); state->ascii_only = RTEST(tmp); tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode)); state->quirks_mode = RTEST(tmp); return self; }
int get_token_value() { //printf("src[%d]:%c\n" , pos , src[pos] ); char * str = src; if (str[pos] == '\0') return LEXEOF; /* Returns end of file */ if(str[pos] == ' ' ||str[pos] == '\t') { while(str[pos] == ' ' ||str[pos] == '\t') pos++; /* Ignoring whitespace */ return get_token_value(); } if(!strncmp( &str[pos] , "//" , 2)) { pos += 2; while( str[pos] != '\n' && str[pos++] != '\0'); // Ignoring line comments return get_token_value(); } if(!strncmp( &str[pos] , "/*" , 2)) { pos += 2; while(pos++) /* Ignoring block comments */ { if(str[pos] == '*') if(str[++pos] == '/') return get_token_value(pos++); if(str[pos] == '\0') return LEXEOF; } } start_pos = pos; /* Keeping reference of the previous token */ if ( str[pos] == ';' ) return str[pos++]; /* Optional semi-colon (;) support */ else if ( str[pos] == '=' ) /* Checks the equal sign (=) */ { pos++; if(in_cond) return EQ; /* Returns equality compariosn if in condition */ return ASSIGN; /* Returns assingment operation */ } else if ( !strncmp(&str[pos] , "*/" , 2)) /* Used for block comments */ { pos += 2; return CMNTEND; } else if ( is_in(str[pos] , "!()+-*/<>,^[]{}\n") ) /* These characters are checked with their ASCII value */ { switch(str[pos]) { case '>': if(str[pos+1] == '=') { pos++; return GE; } break; /* Returns greater than or equal comparison */ case '<': if(str[pos+1] == '=') { pos++; return LE; } break; /* Returns less than or equal comparison */ case '!': if(str[pos+1] == '=') { pos++; return NE; } break; /* Returns not equal comparison */ } return str[pos++]; /* Otherwise return what was found */ } else if (is_digit(str[pos])) /* Checks if a number is found */ { while(is_digit(str[pos]))pos++; /* Skips until the first not number character appears */ if(str[pos] == '.') /* If it has a dot in it .. then it's a floating point number .. saved as double */ { pos++; while(is_digit(str[pos]))pos++; lextext = strndup( &str[start_pos] , pos-start_pos ); return DOUBLE_VAL; } lextext = strndup( &str[start_pos] , pos-start_pos ); return INT_VAL; } else if (is_valid_id_start(str[pos])) /* is either a keyword or an identifier */ { while(is_valid_id_name(str[pos]))pos++; /* Skipps characters , digits and underscores */ lextext = strndup( &str[start_pos] , pos-start_pos ); if(in_table) return ID; int len = strlen(lextext); /* Checking if it's a keyword */ if (!strcmp(lextext, "if" ) && len == 2) return IF; else if (!strcmp(lextext, "then" ) && len == 4) return THEN; else if (!strcmp(lextext, "end" ) && len == 3) return END; else if (!strcmp(lextext, "while" ) && len == 5) return WHILE; else if (!strcmp(lextext, "do" ) && len == 2) return DO; else if (!strcmp(lextext, "function" ) && len == 8) return FUNC; else if (!strcmp(lextext, "return" ) && len == 6) return RETURN; else if (!strcmp(lextext, "for" ) && len == 3) return FOR; return ID; /* Otherwise it's an identifier */ } else if ( str[pos] == '"' ) { pos++; while(str[pos] != '"') pos++; lextext = fstrndup( &str[start_pos+1] , pos - start_pos -1); pos++; return STRING_VAL; } /* else if ( str[pos] == '"' ) { pos++; while(str[pos] != '"')pos++; lextext = strndup( &str[start_pos] , pos - start_pos); pos++; return STRING_VAL; } */ pos++; /* /* Unexpected symbol in the source code fprintf( stderr , "unexpected symbol in line %d:\n" , pos_y ); /* Printing from cur_line_start_pos until new line int s_c = pos - cur_line_start_pos - 1; while(str[cur_line_start_pos] != '\n') fprintf( stderr , "%c" , str[cur_line_start_pos++] ); fprintf(stderr, "\n"); int m; for(m=0; m < s_c ; m++) fprintf(stderr , " "); fprintf(stderr , "^\n"); exit(0); */ }