static void advance_pos (TextgenTemplate *tpl, const gchar *text, gint length, gint *pos, gint *line, gint *column, GError **error) { const gchar *next_char = g_utf8_find_next_char (text + *pos, text + length + 1); if (!next_char) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, *line, *column, _("Invalid UTF-8 character")); set_parse_error (error); return; } if (text[*pos] == '\n') { (*line)++; *column = 1; } else (*column)++; *pos = next_char - text; }
virtual int64_t asInteger() { if(isConstant()) { VariableDeclaration *vdecl = id->getDeclaration()->variableDeclaration(); if(vdecl && vdecl->value) { return vdecl->value->asInteger(); } } else { emit_message(msg::ERROR, "attempt to convert non-const identifier to int", loc); } return 0; }
static void emit_log(struct lio *lio, char *key, char *val, char *key1, char *val1, char *key2, char *val2) { char buf[128] = {}; size_t len; len = emit_message(buf, LOGPOOL_EVENT_WRITE, 3, strlen(key), strlen(val), key, val, strlen(key1), strlen(val1), key1, val1, strlen(key2), strlen(val2), key2, val2, NULL); fprintf(stderr, "len=%zd, buf=%s\n", len, buf+LOG_PROTOCOL_SIZE*4); assert(lio_Write(lio, buf, len) == LIO_OK); }
Expression *Expression::coerceTo(ASTType *ty) { ASTType *expty = getType(); if(expty->is(ty)) { return this; } if(coercesTo(ty)) { //TODO: note in AST that this is implicit return new CastExpression(ty, this, loc); } emit_message(msg::ERROR, "attempt to coerce expression of type '" + expty->getName() + "' to incompatible type '" + ty->getName() + "'", loc); return NULL; }
static Node * parse_list (TextgenTemplate *tpl, GList *tokens, CheckEndFunc check_end, GList **end, GError **error) { gboolean success = TRUE; GList *list = NULL; GList *l; l = tokens; while (l && !(check_end && check_end (l))) { Token *token = l->data; if (token->type == TOKEN_TEXT) { Node *node; node = g_slice_new (Node); node->type = NODE_TEXT; node->value.text.text = token->content; node->value.text.length = token->content_length; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_VARIABLE) { Node *node; node = g_slice_new (Node); node->type = NODE_VARIABLE; node->value.variable.name = token->content; node->value.variable.line = token->line; node->value.variable.column = token->column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_EXPRESSION || token->type == TOKEN_SCRIPT) { Node *node; node = g_slice_new (Node); node->type = token->type == TOKEN_EXPRESSION ? NODE_EXPRESSION : NODE_SCRIPT; node->value.script.code = token->content; node->value.script.length = token->content_length; node->value.script.code_line = token->line; node->value.script.code_column = token->content_column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else if (token->type == TOKEN_COMMAND) { if (g_ascii_strcasecmp (token->command, "IF") == 0) { Node *node; GList *end; GError *tmp_error = NULL; node = parse_condition (tpl, l, &end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } list = g_list_prepend (list, node); l = end->next; } else if (g_ascii_strcasecmp (token->command, "INCLUDE") == 0) { Node *node; node = g_slice_new (Node); node->type = NODE_INCLUDE; node->value.script.code = token->content; node->value.script.length = token->content_length; node->value.script.code_line = token->line; node->value.script.code_column = token->content_column; token->owns_content = FALSE; list = g_list_prepend (list, node); l = l->next; } else { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, token->line, token->column, _("Unknown command %s"), token->command); set_parse_error (error); success = FALSE; goto finish; } } } if (end) *end = l; finish: if (success) { Node *node = g_slice_new (Node); node->type = NODE_LIST; node->value.list = g_list_reverse (list); return node; } else { g_list_free_full (list, free_node); return NULL; } }
static Node * parse_condition (TextgenTemplate *tpl, GList *tokens, GList **end, GError **error) { Token *start_token = tokens->data; Token *end_token; gboolean success = TRUE; Node *if_true = NULL; Node *if_false = NULL; GList *tmp_end = NULL; GError *tmp_error = NULL; if_true = parse_list (tpl, tokens->next, check_condition_if_true_end, &tmp_end, &tmp_error); if (tmp_error != NULL) { success = FALSE; g_propagate_error (error, tmp_error); goto finish; } if (tmp_end == NULL) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_token->line, start_token->column, _("Could not find ENDIF of the condition")); set_parse_error (error); success = FALSE; goto finish; } end_token = tmp_end->data; if (g_ascii_strcasecmp (end_token->command, "ELSEIF") == 0) { if_false = parse_condition (tpl, tmp_end, &tmp_end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } } else if (g_ascii_strcasecmp (end_token->command, "ELSE") == 0) { if_false = parse_list (tpl, tmp_end->next, check_condition_if_false_end, &tmp_end, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } if (tmp_end == NULL) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_token->line, start_token->column, _("Could not find ENDIF of the condition")); set_parse_error (error); success = FALSE; goto finish; } } finish: if (success) { Node *node; node = g_slice_new (Node); node->type = NODE_CONDITION; node->value.cond.code = start_token->content; node->value.cond.length = start_token->content_length; node->value.cond.if_true = if_true; node->value.cond.if_false = if_false; node->value.cond.code_line = start_token->line; node->value.cond.code_column = start_token->column; start_token->owns_content = FALSE; *end = tmp_end; return node; } else { if (if_true) free_node (if_true); if (if_false) free_node (if_false); return FALSE; } }
static Token * maybe_parse_instruction (TextgenTemplate *tpl, const gchar *text, gint length, gint start, gint start_line, gint start_column, gboolean *ignore_empty_line, gint *after_end, gint *after_end_line, gint *after_end_column, GError **error) { gboolean success = TRUE; gboolean found_end = FALSE; gchar instr; gint content_offset; gchar *command = NULL; gchar *content = NULL; gint content_length; gint pos = start; gint cur_line = start_line; gint cur_column = start_column; GError *tmp_error = NULL; if (start < length - 1 && text[start] == '[') { if (text[start + 1] == '!') { *ignore_empty_line = TRUE; instr = text[start + 2]; content_offset = 3; } else { *ignore_empty_line = FALSE; instr = text[start + 1]; content_offset = 2; } if (!IS_VALID_INSTRUCTION_CHAR (instr)) return NULL; } else return NULL; pos += content_offset; cur_column += content_offset; while (pos < length) { if (pos < length - 1 && text[pos] == instr && text[pos + 1] == ']') { gint content_start = start + content_offset; content_length = pos - content_start; content = g_strndup (text + content_start, content_length); *after_end = pos + 2; cur_column += 2; found_end = TRUE; break; } advance_pos (tpl, text, length, &pos, &cur_line, &cur_column, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } } if (!found_end) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column, _("Could not find the end of the instruction"), instr); set_parse_error (error); success = FALSE; goto finish; } if (instr == TOKEN_COMMAND) { static GRegex *regex = NULL; GMatchInfo *match_info; gchar *old_content = content; gint start_pos; gint end_pos; if (!regex) regex = g_regex_new ("^\\s*([A-Za-z]+)\\s+(.*)$", G_REGEX_MULTILINE | G_REGEX_OPTIMIZE, 0, NULL); if (!g_regex_match (regex, old_content, 0, &match_info)) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column, _("A command must look like this: [# COMMAND content #]")); set_parse_error (error); success = FALSE; goto finish; } command = g_match_info_fetch (match_info, 1); content = g_match_info_fetch (match_info, 2); g_match_info_fetch_pos (match_info, 2, &start_pos, &end_pos); content_length = end_pos - start_pos; g_match_info_free (match_info); g_free (old_content); } *after_end_line = cur_line; *after_end_column = cur_column; finish: if (success) { Token *token = g_slice_new (Token); token->type = instr; token->command = command; token->content = content; token->content_length = content_length; token->line = start_line; token->column = start_column; token->content_column = start_column + content_offset; token->owns_content = TRUE; token->owns_command = TRUE; return token; } else { g_free (command); g_free (content); return NULL; } }
virtual int64_t asInteger() { emit_message(msg::ERROR, "this value cannot be converted to integer", loc); return 0; }
virtual long getMemberIndex(std::string member) { emit_message(msg::FAILURE, "member index is meaningless for interface"); return 0; }