char* parse_symbol(char** c) { char* curr = *c; while(is_whitespace(*curr)) curr++; if(!is_symbol_char(*curr)) return NULL; char* start = curr; while(is_symbol_char(*curr)) { curr++; } char* buffer = new char[(curr + 1 - start) * sizeof(char)]; strncpy(buffer, start, (curr - start)); buffer[curr-start] = '\0'; *c = curr; return buffer; }
static gchar * get_word_to_cursor (const GtkTextIter *location) { GtkTextIter iter = *location; GtkTextIter end = *location; if (!gtk_text_iter_backward_char (&end)) return NULL; while (gtk_text_iter_backward_char (&iter)) { gunichar ch; ch = gtk_text_iter_get_char (&iter); if (!is_symbol_char (ch)) break; } if (!is_symbol_char (gtk_text_iter_get_char (&iter))) gtk_text_iter_forward_char (&iter); if (gtk_text_iter_compare (&iter, &end) >= 0) return NULL; return gtk_text_iter_get_slice (&iter, location); }
static int next_token(char *code, int *start, int *end) { int c; *start = *end; while (code[*start] && (skip_spaces(code, start) || skip_comments(code, start))) ; *end = *start + 1; c = code[*start]; if (c == '(') return TK_PAREN_OPEN; else if (c == ')') return TK_PAREN_CLOSE; else if (c == '.') return TK_DOT; else if (c >= '0' && c <= '9') { while (code[*end] && ((code[*end] >= '0' && code[*end] <= '9') || (code[*end] == '.'))) ++(*end); return TK_NUMBER; } else if (is_symbol_char(c)) { while (code[*end] && is_symbol_char(code[*end])) ++(*end); return TK_SYMBOL; } else { return TK_EOF; } }
pointer parse_expr(parser* parse) { eat_whitespace(parse); pointer ret_car; pointer ret_cdr; switch(*parse->curr) { case '(': parse->curr++; ret_car = parse_expr(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); case '"': ret_car = parse_string(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); case '\'': parse->curr++; ret_car = parse_quote(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); case ')': parse->curr++; return NIL; case '+': case '-': case 'b': ret_car = parse_number_or_symbol(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); case '.': return parse_number_or_pair(parse); case '\\': parse->curr++; ret_car = create_char(*(parse->curr++)); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); case ';': while(!is_newline(*parse->curr) && *parse->curr != '\0') parse->curr++; return parse_expr(parse); case 0: return NIL; default: if(is_number_char(*parse->curr)) { ret_car = parse_number(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); } else if(is_symbol_char(*parse->curr)) { ret_car = parse_symbol(parse); ret_cdr = parse_expr(parse); return create_pair(ret_car, ret_cdr); } else return parser_error(parse, "Unexpected char in expression."); } parse->curr++; }
int tokenizer_next(struct tokenizer* tokenizer) //@ requires Tokenizer(tokenizer); //@ ensures Tokenizer(tokenizer); { int c; int token; string_buffer_clear(tokenizer->buffer); tokenizer_skip_whitespace(tokenizer); c = tokenizer_peek(tokenizer); if ( c == '(' || c == ')' || c == -1 ) { tokenizer_drop(tokenizer); token = c; } else if ( is_digit(c) ) { token = tokenizer_eat_number(tokenizer); } else if ( is_symbol_char(c) ) { token = tokenizer_eat_symbol(tokenizer); } else { tokenizer_drop(tokenizer); token = 'B'; // bad character } tokenizer->lasttoken = token; return token; }
pointer parse_symbol(parser* parse) { const char* C = parse->curr; while(!is_delimiter(*parse->curr)) { if(is_symbol_char(*parse->curr)) parse->curr++; else return parser_error(parse, "Unexpected char '%c' in symbol.", *parse->curr); } return create_symbol(parse->symbols, C, parse->curr-C); }
pointer parse_quote(parser* parse) { if(is_whitespace(*parse->curr)) return parser_error(parse, "unexpected whitespace after quote."); switch(*parse->curr) { case '(': return create_pair(create_symbol(parse->symbols, "QUOTE"), parse_expr(parse)); default: if(is_symbol_char(*parse->curr) && !is_number_char(*parse->curr)) return create_pair(create_symbol(parse->symbols, "QUOTE"), parse_symbol(parse)); else return parser_error(parse, "Unexpected token after quote."); } }
int tokenizer_eat_symbol(struct tokenizer* tokenizer) //@ requires Tokenizer(tokenizer); //@ ensures Tokenizer(tokenizer); { for (;;) //@ invariant Tokenizer(tokenizer); { int result; bool isSymbolChar; result = tokenizer_peek(tokenizer); isSymbolChar = is_symbol_char(result); if (!isSymbolChar) break; result = tokenizer_next_char(tokenizer); string_buffer_append_char(tokenizer->buffer, (char)result); } return 'S'; }
static bool parse_argument(const char *string, /* original user string */ const char **ret_p, /* start of argument IN:OUT */ const cg_blend_string_statement_t *statement, int current_arg, cg_blend_string_argument_t *arg, /* OUT */ cg_error_t **error) { const char *p = *ret_p; const char *mark = NULL; const char *error_string = NULL; parser_arg_state_t state = PARSER_ARG_STATE_START; bool parsing_factor = false; bool implicit_factor_brace; arg->source.is_zero = false; arg->source.info = NULL; arg->source.texture = 0; arg->source.one_minus = false; arg->source.mask = statement->mask; arg->factor.is_one = false; arg->factor.is_color = false; arg->factor.is_src_alpha_saturate = false; arg->factor.source.is_zero = false; arg->factor.source.info = NULL; arg->factor.source.texture = 0; arg->factor.source.one_minus = false; arg->factor.source.mask = statement->mask; do { if (c_ascii_isspace(*p)) continue; if (*p == '\0') { error_string = "Unexpected end of string while parsing argument"; goto error; } switch (state) { case PARSER_ARG_STATE_START: if (*p == '1') state = PARSER_ARG_STATE_EXPECT_MINUS; else if (*p == '0') { arg->source.is_zero = true; state = PARSER_ARG_STATE_EXPECT_END; } else { p--; /* backtrack */ state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; } continue; case PARSER_ARG_STATE_EXPECT_MINUS: if (*p != '-') { error_string = "expected a '-' following the 1"; goto error; } arg->source.one_minus = true; state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; continue; case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME: if (!is_symbol_char(*p)) { error_string = "expected a color source name"; goto error; } state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME; mark = p; if (parsing_factor) arg->factor.is_color = true; /* fall through */ case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: if (!is_symbol_char(*p)) { cg_blend_string_color_source_t *source = parsing_factor ? &arg->factor.source : &arg->source; source->info = get_color_src_info(mark, p); if (!source->info) { error_string = "Unknown color source name"; goto error; } state = PARSER_ARG_STATE_MAYBE_COLOR_MASK; } else continue; /* fall through */ case PARSER_ARG_STATE_MAYBE_COLOR_MASK: if (*p != '[') { p--; /* backtrack */ if (!parsing_factor) state = PARSER_ARG_STATE_MAYBE_MULT; else state = PARSER_ARG_STATE_EXPECT_END; continue; } state = PARSER_ARG_STATE_SCRAPING_MASK; mark = p; /* fall through */ case PARSER_ARG_STATE_SCRAPING_MASK: if (*p == ']') { size_t len = p - mark; cg_blend_string_color_source_t *source = parsing_factor ? &arg->factor.source : &arg->source; if (len == 5 && strncmp(mark, "[RGBA", len) == 0) { if (statement->mask != CG_BLEND_STRING_CHANNEL_MASK_RGBA) { error_string = "You can't use an RGBA color mask if the " "statement hasn't also got an RGBA= mask"; goto error; } source->mask = CG_BLEND_STRING_CHANNEL_MASK_RGBA; } else if (len == 4 && strncmp(mark, "[RGB", len) == 0) source->mask = CG_BLEND_STRING_CHANNEL_MASK_RGB; else if (len == 2 && strncmp(mark, "[A", len) == 0) source->mask = CG_BLEND_STRING_CHANNEL_MASK_ALPHA; else { error_string = "Expected a channel mask of [RGBA]" "[RGB] or [A]"; goto error; } if (parsing_factor) state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; else state = PARSER_ARG_STATE_MAYBE_MULT; } continue; case PARSER_ARG_STATE_EXPECT_OPEN_PAREN: if (*p != '(') { if (is_alphanum_char(*p)) { p--; /* compensate for implicit brace and ensure this * char gets considered part of the blend factor */ implicit_factor_brace = true; } else { error_string = "Expected '(' around blend factor or alpha " "numeric character for blend factor name"; goto error; } } else implicit_factor_brace = false; parsing_factor = true; state = PARSER_ARG_STATE_EXPECT_FACTOR; continue; case PARSER_ARG_STATE_EXPECT_FACTOR: if (*p == '1') state = PARSER_ARG_STATE_MAYBE_MINUS; else if (*p == '0') { arg->source.is_zero = true; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } else { state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE; mark = p; } continue; case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE: if (!is_symbol_char(*p)) { size_t len = p - mark; if (len >= strlen("SRC_ALPHA_SATURATE") && strncmp(mark, "SRC_ALPHA_SATURATE", len) == 0) { arg->factor.is_src_alpha_saturate = true; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } else { state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; p = mark - 1; /* backtrack */ } } continue; case PARSER_ARG_STATE_MAYBE_MINUS: if (*p == '-') { if (implicit_factor_brace) { error_string = "Expected ( ) braces around blend factor with " "a subtraction"; goto error; } arg->factor.source.one_minus = true; state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; } else { arg->factor.is_one = true; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } continue; case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN: if (implicit_factor_brace) { p--; state = PARSER_ARG_STATE_EXPECT_END; continue; } if (*p != ')') { error_string = "Expected closing parenthesis after blend factor"; goto error; } state = PARSER_ARG_STATE_EXPECT_END; continue; case PARSER_ARG_STATE_MAYBE_MULT: if (*p == '*') { state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN; continue; } arg->factor.is_one = true; state = PARSER_ARG_STATE_EXPECT_END; /* fall through */ case PARSER_ARG_STATE_EXPECT_END: if (*p != ',' && *p != ')') { error_string = "expected , or )"; goto error; } *ret_p = p - 1; return true; } } while (p++); error: { int offset = p - string; _cg_set_error(error, CG_BLEND_STRING_ERROR, CG_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, "Syntax error for argument %d at offset %d: %s", current_arg, offset, error_string); if (CG_DEBUG_ENABLED(CG_DEBUG_BLEND_STRINGS)) { c_debug("Syntax error for argument %d at offset %d: %s", current_arg, offset, error_string); } return false; } }
/* Load config from file */ static int load_from_file(const char * confname) { vfs68_t * is = 0; char s[256], * word; int err; option68_t * opt; strcpy(s, "sc68://config/"); strcat(s, confname); is = uri68_vfs(s, 1, 0); err = vfs68_open(is); if (err) goto error; for(;;) { char * name; int i, len, c = 0; len = vfs68_gets(is, s, sizeof(s)); if (len == -1) { err = -1; break; } if (len == 0) { break; } i = 0; /* Skip space */ while (i < len && (c=s[i++], isspace(c))) ; if (!is_symbol_char(c)) { continue; } /* Get symbol name. */ name = s+i-1; while (i < len && is_symbol_char(c = s[i++])) if (c == '_') s[i-1] = c = '-'; s[i-1] = 0; /* TRACE68(config68_cat,"conf68: load get key name='%s\n", name); */ /* Skip space */ while (i < len && isspace(c)) c=s[i++]; /* Must have '=' */ if (c != '=') { continue; } c=s[i++]; /* Skip space */ while (i < len && isspace(c)) c=s[i++]; word = s + i - 1; while (i < len && (c = s[i++]) && c != '\n'); s[i-1] = 0; opt = option68_get(name, opt68_ALWAYS); if (!opt) { TRACE68(config68_cat, "conf68: unknown config key '%s'='%s'\n", name, word); continue; } if (!opt->save) { TRACE68(config68_cat, "conf68: config key '%s'='%s' not for save\n", name, word); } TRACE68(config68_cat, "conf68: set name='%s'='%s'\n", name, word); option68_set(opt, word, opt68_PRIO, opt68_CFG); } error: vfs68_destroy(is); TRACE68(config68_cat, "conf68: loaded => [%s]\n",strok68(err)); return err; }
static gboolean parse_argument (const char *string, /* original user string */ const char **ret_p, /* start of argument IN:OUT */ const CoglBlendStringStatement *statement, int current_arg, CoglBlendStringArgument *arg, /* OUT */ CoglBlendStringContext context, GError **error) { const char *p = *ret_p; const char *mark = NULL; const char *error_string = NULL; ParserArgState state = PARSER_ARG_STATE_START; gboolean parsing_factor = FALSE; arg->source.is_zero = FALSE; arg->source.info = NULL; arg->source.texture = 0; arg->source.one_minus = FALSE; arg->source.mask = statement->mask; arg->factor.is_one = FALSE; arg->factor.is_color = FALSE; arg->factor.is_src_alpha_saturate = FALSE; arg->factor.source.is_zero = FALSE; arg->factor.source.info = NULL; arg->factor.source.texture = 0; arg->factor.source.one_minus = FALSE; arg->factor.source.mask = statement->mask; do { if (g_ascii_isspace (*p)) continue; if (*p == '\0') { error_string = "Unexpected end of string while parsing argument"; goto error; } switch (state) { case PARSER_ARG_STATE_START: if (*p == '1') state = PARSER_ARG_STATE_EXPECT_MINUS; else if (*p == '0') { arg->source.is_zero = TRUE; state = PARSER_ARG_STATE_EXPECT_END; } else { p--; /* backtrack */ state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; } continue; case PARSER_ARG_STATE_EXPECT_MINUS: if (*p != '-') { error_string = "expected a '-' following the 1"; goto error; } arg->source.one_minus = TRUE; state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; continue; case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME: if (!is_symbol_char (*p)) { error_string = "expected a color source name"; goto error; } state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME; mark = p; if (parsing_factor) arg->factor.is_color = TRUE; /* fall through */ case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: if (!is_symbol_char (*p)) { CoglBlendStringColorSource *source = parsing_factor ? &arg->factor.source : &arg->source; source->info = get_color_src_info (mark, p, context); if (!source->info) { error_string = "Unknown color source name"; goto error; } if (source->info->type == COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N) { char *endp; source->texture = strtoul (&mark[strlen ("TEXTURE_")], &endp, 10); if (mark == endp) { error_string = "invalid texture number given with " "TEXTURE_N color source"; goto error; } p = endp; } state = PARSER_ARG_STATE_MAYBE_COLOR_MASK; } else continue; /* fall through */ case PARSER_ARG_STATE_MAYBE_COLOR_MASK: if (*p != '[') { p--; /* backtrack */ if (!parsing_factor) state = PARSER_ARG_STATE_MAYBE_MULT; else state = PARSER_ARG_STATE_EXPECT_END; continue; } state = PARSER_ARG_STATE_SCRAPING_MASK; mark = p; /* fall through */ case PARSER_ARG_STATE_SCRAPING_MASK: if (*p == ']') { gsize len = p - mark; CoglBlendStringColorSource *source = parsing_factor ? &arg->factor.source : &arg->source; if (len == 5 && strncmp (mark, "[RGBA", len) == 0) { if (statement->mask != COGL_BLEND_STRING_CHANNEL_MASK_RGBA) { error_string = "You can't use an RGBA color mask if the " "statement hasn't also got an RGBA= mask"; goto error; } source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; } else if (len == 4 && strncmp (mark, "[RGB", len) == 0) source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; else if (len == 2 && strncmp (mark, "[A", len) == 0) source->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; else { error_string = "Expected a channel mask of [RGBA]" "[RGB] or [A]"; goto error; } if (parsing_factor) state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; else state = PARSER_ARG_STATE_MAYBE_MULT; } continue; case PARSER_ARG_STATE_EXPECT_OPEN_PAREN: if (*p != '(') { error_string = "Expected '(' before blend factor - the parser " "currently requires that all blend factors " "following a '*' be surrounded in brackets"; goto error; } parsing_factor = TRUE; state = PARSER_ARG_STATE_EXPECT_FACTOR; continue; case PARSER_ARG_STATE_EXPECT_FACTOR: if (*p == '1') state = PARSER_ARG_STATE_MAYBE_MINUS; else if (*p == '0') { arg->source.is_zero = TRUE; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } else { state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE; mark = p; } continue; case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE: if (!is_symbol_char (*p)) { gsize len = p - mark; if (len >= strlen ("SRC_ALPHA_SATURATE") && strncmp (mark, "SRC_ALPHA_SATURATE", len) == 0) { arg->factor.is_src_alpha_saturate = TRUE; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } else { state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; p = mark - 1; /* backtrack */ } } continue; case PARSER_ARG_STATE_MAYBE_MINUS: if (*p == '-') { arg->factor.source.one_minus = TRUE; state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; } else { arg->factor.is_one = TRUE; state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; } continue; case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN: if (*p != ')') { error_string = "Expected closing parenthesis after blend factor"; goto error; } state = PARSER_ARG_STATE_EXPECT_END; continue; case PARSER_ARG_STATE_MAYBE_MULT: if (*p == '*') { state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN; continue; } arg->factor.is_one = TRUE; state = PARSER_ARG_STATE_EXPECT_END; /* fall through */ case PARSER_ARG_STATE_EXPECT_END: if (*p != ',' && *p != ')') { error_string = "expected , or )"; goto error; } *ret_p = p - 1; return TRUE; } } while (p++); error: { int offset = p - string; g_set_error (error, COGL_BLEND_STRING_ERROR, COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, "Syntax error for argument %d at offset %d: %s", current_arg, offset, error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { g_debug ("Syntax error for argument %d at offset %d: %s", current_arg, offset, error_string); } return FALSE; } }