bool hplugins_addpacket(unsigned short cmd, unsigned short length, void (*receive) (int fd), unsigned int point, unsigned int pluginID) { struct HPluginPacket *packet; int i; if (point >= hpPHP_MAX) { ShowError("HPM->addPacket:%s: unknown point '%u' specified for packet 0x%04x (len %d)\n",HPM->pid2name(pluginID),point,cmd,length); return false; } for (i = 0; i < VECTOR_LENGTH(HPM->packets[point]); i++) { if (VECTOR_INDEX(HPM->packets[point], i).cmd == cmd ) { ShowError("HPM->addPacket:%s: can't add packet 0x%04x, already in use by '%s'!", HPM->pid2name(pluginID), cmd, HPM->pid2name(VECTOR_INDEX(HPM->packets[point], i).pluginID)); return false; } } VECTOR_ENSURE(HPM->packets[point], 1, 1); VECTOR_PUSHZEROED(HPM->packets[point]); packet = &VECTOR_LAST(HPM->packets[point]); packet->pluginID = pluginID; packet->cmd = cmd; packet->len = length; packet->receive = receive; return true; }
t3_highlight_match_t *t3_highlight_new_match(const t3_highlight_t *highlight) { t3_highlight_match_t *result = malloc(sizeof(t3_highlight_match_t)); if (result == NULL) return NULL; VECTOR_INIT(result->mapping); if (!VECTOR_RESERVE(result->mapping)) { free(result); return NULL; } result->highlight = highlight; memset(&VECTOR_LAST(result->mapping), 0, sizeof(state_mapping_t)); t3_highlight_reset(result, 0); return result; }
/** * Adds a configuration listener for a plugin. * * @param pluginID The plugin identifier. * @param type The configuration type to listen for. * @param name The configuration entry name. * @param func The callback function. * @retval true if the listener was added successfully. * @retval false in case of error. */ bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key)) { struct HPConfListenStorage *conf; int i; if (parse_func == NULL) { ShowError("HPM->addConf:%s: missing setter function for config '%s'\n",HPM->pid2name(pluginID),name); return false; } if (type == HPCT_BATTLE && return_func == NULL) { ShowError("HPM->addConf:%s: missing getter function for config '%s'\n",HPM->pid2name(pluginID),name); return false; } if (type >= HPCT_MAX) { ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name); return false; } ARR_FIND(0, VECTOR_LENGTH(HPM->config_listeners[type]), i, strcmpi(name, VECTOR_INDEX(HPM->config_listeners[type], i).key) == 0); if (i != VECTOR_LENGTH(HPM->config_listeners[type])) { ShowError("HPM->addConf:%s: duplicate '%s', already in use by '%s'!", HPM->pid2name(pluginID), name, HPM->pid2name(VECTOR_INDEX(HPM->config_listeners[type], i).pluginID)); return false; } VECTOR_ENSURE(HPM->config_listeners[type], 1, 1); VECTOR_PUSHZEROED(HPM->config_listeners[type]); conf = &VECTOR_LAST(HPM->config_listeners[type]); conf->pluginID = pluginID; safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH); conf->parse_func = parse_func; conf->return_func = return_func; return true; }
static dst_idx_t find_state(t3_highlight_match_t *match, pattern_idx_t highlight_state, pattern_extra_t *extra, const char *dynamic_line, int dynamic_length, const char *dynamic_pattern) { size_t i; if (highlight_state <= EXIT_STATE) { dst_idx_t return_state; for (return_state = match->state; highlight_state < EXIT_STATE && return_state > 0; highlight_state++) return_state = match->mapping.data[return_state].parent; return return_state > 0 ? match->mapping.data[return_state].parent : 0; } if (highlight_state == NO_CHANGE) return match->state; /* Check if the state is already mapped. */ for (i = match->state + 1; i < match->mapping.used; i++) { if (match->mapping.data[i].parent == match->state && match->mapping.data[i].highlight_state == highlight_state && /* Either neither is a match with dynamic back reference, or both are. For safety we ensure that the found state actually has information about a dynamic back reference. */ (extra == NULL || (extra != NULL && extra->dynamic_name != NULL && match->mapping.data[i].dynamic != NULL && dynamic_length == match->mapping.data[i].dynamic->extracted_length && memcmp(dynamic_line, match->mapping.data[i].dynamic->extracted, dynamic_length) == 0))) return i; } if (!VECTOR_RESERVE(match->mapping)) return 0; VECTOR_LAST(match->mapping).parent = match->state; VECTOR_LAST(match->mapping).highlight_state = highlight_state; VECTOR_LAST(match->mapping).dynamic = NULL; if (extra != NULL && extra->dynamic_name != NULL) { int replace_count = 0, i; char *pattern, *patptr; dynamic_state_t *new_dynamic; for (i = 0; i < dynamic_length; i++) { if (dynamic_line[i] == 0 || (dynamic_line[i] == '\\' && i + 1 < dynamic_length && dynamic_line[i + 1] == 'E')) replace_count++; } /* Build the following pattern: (?(DEFINE)(?<%s>\Q%s\E))%s Note that the pattern between \Q and \E must be escaped for 0 bytes and \E. */ /* 22 bytes for fixed prefix and 0 byte, dynamic_length for the matched text, 5 * replace_count for replacing 0 bytes and the \ in any \E's in the matched text, the length of the name of the pattern to insert and the length of the original regular expression to be inserted. */ if ((pattern = malloc(21 + dynamic_length + replace_count * 5 + strlen(extra->dynamic_name) + strlen(dynamic_pattern))) == NULL) { /* Undo VECTOR_RESERVE performed above. */ match->mapping.used--; return 0; } if ((new_dynamic = malloc(sizeof(dynamic_state_t))) == NULL) { /* Undo VECTOR_RESERVE performed above. */ match->mapping.used--; free(pattern); return 0; } if ((new_dynamic->extracted = malloc(dynamic_length)) == NULL) { /* Undo VECTOR_RESERVE performed above. */ match->mapping.used--; free(new_dynamic); free(pattern); return 0; } new_dynamic->extracted_length = dynamic_length; memcpy(new_dynamic->extracted, dynamic_line, dynamic_length); sprintf(pattern, "(?(DEFINE)(?<%s>\\Q", extra->dynamic_name); patptr = pattern + strlen(pattern); for (i = 0; i < dynamic_length; i++) { if (dynamic_line[i] == 0 || (dynamic_line[i] == '\\' && i + 1 < dynamic_length && dynamic_line[i + 1] == 'E')) { *patptr++ = '\\'; *patptr++ = 'E'; *patptr++ = '\\'; *patptr++ = dynamic_line[i] == 0 ? '0' : '\\'; *patptr++ = '\\'; *patptr++ = 'Q'; } else { *patptr++ = dynamic_line[i]; } } strcpy(patptr, "\\E))"); strcat(patptr, dynamic_pattern); if (!_t3_compile_highlight(pattern, &new_dynamic->regex, NULL, match->highlight->flags & ~T3_HIGHLIGHT_VERBOSE_ERROR, NULL)) { /* Undo VECTOR_RESERVE performed above. */ match->mapping.used--; free(new_dynamic->extracted); free(new_dynamic); free(pattern); return 0; } VECTOR_LAST(match->mapping).dynamic = new_dynamic; free(pattern); } return match->mapping.used - 1; }