int tre_lexer_next(tre_Lexer* lex) { int len; uint32_t code; uint32_t* name; if (lex->scur == lex->slen) { lex->token.value = TK_END; return 0; } code = char_next(lex); bool is_lastone = (lex->scur == lex->slen); switch (lex->state) { case 0: // NORMAL STATE if (token_check(code)) { lex->token.extra.code = 0; lex->token.value = code; // token val is it's own ascii. switch (code) { case '[': lex->state = 1; if ((!is_lastone) && char_lookahead(lex) == '^') { lex->token.extra.code = 1; } break; case '{': { int count; int scur_bak = lex->scur; int llimit = 0, rlimit = -1; // read left limit a{1 llimit = read_int(lex, 0, &count); if (count == 0) goto __bad_token; code = char_nextn(lex, count+1); // read comma a{1, if ((char)code == ',') { //char_next(lex); } else if ((char)code == '}') { rlimit = llimit; goto __write_code; } else { // falied, rollback goto __bad_token; } // read left limit a{1, 2 rlimit = read_int(lex, 0, &count); code = char_nextn(lex, count+1); // read right brace a{1,2} or a{1,} if ((char)code == '}') { // ok, rlimit is -1 } else { // falied, rollback goto __bad_token; } __write_code: lex->token.extra.code = llimit; lex->token.extra.code2 = rlimit; break; __bad_token: lex->token.value = TK_CHAR; lex->token.extra.code = '{'; lex->scur = scur_bak; break; } case '(': { code = char_lookahead(lex); // if next char is not ? if (code != '?') { lex->token.extra.group_type = GT_NORMAL; lex->token.extra.group_name = NULL; break; } else { code = char_nextn(lex, 2); switch (code) { case '#': { // just comment bool is_escape = false; code = char_next(lex); while (!(!is_escape && code == ')')) { code = char_next(lex); if (is_escape) is_escape = false; if (code == '\\') is_escape = true; if (code == '\0') return ERR_LEXER_UNBALANCED_PARENTHESIS; } lex->token.value = TK_COMMENT; break; } case ':': lex->token.extra.group_type = GT_NONGROUPING; break; case '=': lex->token.extra.group_type = GT_IF_MATCH; break; case '!': lex->token.extra.group_type = GT_IF_NOT_MATCH; break; case '(': // code for conditional backref name = read_group_name(lex, ')', &len); if (name) { code = char_nextn(lex, len); lex->token.extra.group_type = GT_BACKREF_CONDITIONAL_GROUPNAME; lex->token.extra.group_name = name; lex->token.extra.group_name_len = len; } else { int i = read_int(lex, ')', &len); if (i == -1) { return ERR_LEXER_INVALID_GROUP_NAME_OR_INDEX; } else { code = char_nextn(lex, len); lex->token.extra.group_type = GT_BACKREF_CONDITIONAL_INDEX; lex->token.extra.index = i; } } code = char_next(lex); break; case 'P': // group name code = char_lookahead(lex); if (code == '<') { code = char_next(lex); name = read_group_name(lex, '>', &len); if (!name) return ERR_LEXER_BAD_GROUP_NAME; code = char_nextn(lex, len+1); // name and '>' lex->token.extra.group_type = GT_NORMAL; lex->token.extra.group_name = name; lex->token.extra.group_name_len = len; } else if (code == '=') { // code for back reference (?P=) code = char_next(lex); name = read_group_name(lex, ')', &len); if (!name) return ERR_LEXER_BAD_GROUP_NAME_IN_BACKREF; code = char_nextn(lex, len); // skip name lex->token.extra.group_type = GT_BACKREF; lex->token.extra.group_name = name; lex->token.extra.group_name_len = len; } else { return ERR_LEXER_UNKNOW_SPECIFIER; } break; case '<': code = char_next(lex); if (code == '=') { lex->token.extra.group_type = GT_IF_PRECEDED_BY; } else if (code == '!') { lex->token.extra.group_type = GT_IF_NOT_PRECEDED_BY; } else { return ERR_LEXER_UNKNOW_SPECIFIER; } break; default: if (char_to_flag(code)) { int flag = 0; while (true) { flag = char_to_flag(code); if (flag) lex->extra_flag |= flag; else break; code = char_next(lex); } } else { return ERR_LEXER_UNEXPECTED_END_OF_PATTERN; } lex->token.value = TK_NOP; break; } } } }; } else { int ret = token_char_accept(lex, code, true); if (ret) return ret; } break; case 1: { // [...] bool is_escape = code == '\\'; int ret = token_char_accept(lex, code, false); if (ret) return ret; if (!is_escape && lex->token.value == TK_CHAR) { // end the state if (code == ']') { lex->state = 0; lex->token.value = ']'; break; } } // [a-z] grammar code = char_lookahead(lex); if (code == '-') { uint32_t code2 = char_lookaheadn(lex, 2); // [a-] if (code2 == ']') break; // [\s-1] -> error if (lex->token.value == TK_CHAR_SPE) { return ERR_LEXER_BAD_CHARACTER_RANGE; } // [a-z] code2 = lex->token.extra.code; code = char_nextn(lex, 2); ret = token_char_accept(lex, code, false); if (ret) return ret; // [1-\s] -> error if (lex->token.value == TK_CHAR_SPE) { return ERR_LEXER_BAD_CHARACTER_RANGE; } // [z-a] -> error if (lex->token.extra.code < code2) { return ERR_LEXER_BAD_CHARACTER_RANGE; } // everything is ok lex->token.value = '-'; lex->token.extra.code2 = lex->token.extra.code; lex->token.extra.code = code2; } break; } } return 0; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_label_message //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int controltype_label_message(control *c, int tokencount, char *tokens[]) { // token strings enum { T_NONE = 0, T_STYLE , T_VALIGN , T_HALIGN , T_HASTITLE , T_LOCKPOS , T_PLUGINLOAD , T_PLUGINUNLOAD , T_PLUGINSETPOS , T_PLUGINSHOW , T_PLUGINABOUT }; extern char szWPStyle []; static struct token_check controltype_label_property_tokens[] = { { szWPStyle, T_STYLE , 1 }, { "VAlign", T_VALIGN , 1 }, { "HAlign", T_HALIGN , 1 }, { "HasTitleBar", T_HASTITLE , 1 }, { "IsLocked", T_LOCKPOS , 1 }, { NULL } }; static struct token_check controltype_label_plugin_property_tokens[] = { { "IsVisible", T_PLUGINSHOW , 1 }, { "Position", T_PLUGINSETPOS , 2 }, { NULL } }; static struct token_check controltype_label_plugin_tokens[] = { { "Load", T_PLUGINLOAD , 1 }, { "Unload", T_PLUGINUNLOAD , 1 }, { "About", T_PLUGINABOUT , 0 }, { szBActionPluginSetProperty, (UINT_PTR)controltype_label_plugin_property_tokens , 2 }, { NULL } }; static struct token_check controltype_label_message_tokens[] = { { szBActionSetControlProperty, (UINT_PTR)controltype_label_property_tokens, 2 }, { szBActionPlugin, (UINT_PTR)controltype_label_plugin_tokens, 2 }, { NULL } }; // ----------------- //Get the details controltype_label_details *details = (controltype_label_details *) c->controldetails; //If set control details int i; int curtok = 2; switch (token_check(controltype_label_message_tokens, &curtok, tokencount, tokens)) { // ----------------- case T_STYLE: if (-1 != (i = get_string_index(tokens[curtok], szStyleNames))) { c->windowptr->style = i; style_draw_invalidate(c); return 0; } break; // ----------------- case T_HALIGN: if (-1 != (i = get_string_index(tokens[curtok], label_haligns))) { details->halign = i; controltype_label_updatesettings(details); style_draw_invalidate(c); return 0; } break; // ----------------- case T_VALIGN: if (-1 != (i = get_string_index(tokens[curtok], label_valigns))) { details->valign = i; controltype_label_updatesettings(details); style_draw_invalidate(c); return 0; } break; // ----------------- case T_HASTITLE: if (details->is_frame && config_set_bool(tokens[curtok], &details->has_titlebar)) { style_draw_invalidate(c); return 0; } break; // ----------------- case T_LOCKPOS: if (details->is_frame && config_set_bool(tokens[curtok], &details->is_locked)) return 0; break; // ----------------- case T_PLUGINLOAD: if (details->is_frame) { char *plugin_name = tokens[curtok]; if (0 == strcmp(plugin_name, "*browse*")) { // "open file" dialog plugin_name = dialog_file("Plugins\0*.dll\0", "Add Plugin" , NULL, ".dll", false); if (NULL == plugin_name) { //message_override = true; return 2; } } ModuleInfo * m = loadPlugin(&details->module_info, c->windowptr->hwnd, plugin_name); if (m) { variables_set(false, "LastPlugin", m->module_name); return 0; } } break; // ----------------- case T_PLUGINUNLOAD: if (unloadPlugin(&details->module_info, tokens[curtok])) return 0; break; // ----------------- case T_PLUGINSETPOS: { int x, y; if (config_set_int(tokens[curtok], &x) && config_set_int(tokens[1+curtok], &y) && plugin_setpos(details->plugin_info, tokens[-2+curtok], x, y) ) return 0; return 0; // dont generate an error here... } break; // ----------------- case T_PLUGINSHOW: { bool show; if (plugin_getset_show_state(details->plugin_info, tokens[-2+curtok], config_set_bool(tokens[curtok], &show) ? show : 2) ) return 0; return 0; // dont generate an error here... } break; // ----------------- case T_PLUGINABOUT: { aboutPlugins(details->module_info, c->controlname); return 0; } break; // ----------------- //Must be an agent message default: return agent_controlmessage(c, tokencount, tokens, CONTROLTYPE_LABEL_AGENT_COUNT, details->agents, controltype_label_agentnames, controltype_label_agenttypes); } return 1; }