📄 pval.c
字号:
ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: It's bad form to have a goto in a macro to a target outside the macro!\n", item->filename, item->startline, item->endline); warns++; } } } } }} static void find_pval_goto_item(pval *item, int lev){ struct pval *p4; if (lev>100) { ast_log(LOG_ERROR,"find_pval_goto in infinite loop! item_type: %d\n\n", item->type); return; } switch ( item->type ) { case PV_MACRO: /* fields: item->u1.str == name of macro item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user item->u2.arglist->u1.str == argument item->u2.arglist->next == next arg item->u3.macro_statements == pval list of statements in macro body. */ /* printf("Descending into macro %s at line %d\n", item->u1.str, item->startline); */ find_pval_gotos(item->u3.macro_statements,lev+1); /* if we're just searching for a context, don't bother descending into them */ break; case PV_CONTEXT: /* fields: item->u1.str == name of context item->u2.statements == pval list of statements in context body item->u3.abstract == int 1 if an abstract keyword were present */ break; case PV_CASE: /* fields: item->u1.str == value of case item->u2.statements == pval list of statements under the case */ /* printf("Descending into Case of %s\n", item->u1.str); */ find_pval_gotos(item->u2.statements,lev+1); break; case PV_PATTERN: /* fields: item->u1.str == value of case item->u2.statements == pval list of statements under the case */ /* printf("Descending into Pattern of %s\n", item->u1.str); */ find_pval_gotos(item->u2.statements,lev+1); break; case PV_DEFAULT: /* fields: item->u2.statements == pval list of statements under the case */ /* printf("Descending into default\n"); */ find_pval_gotos(item->u2.statements,lev+1); break; case PV_CATCH: /* fields: item->u1.str == name of extension to catch item->u2.statements == pval list of statements in context body */ /* printf("Descending into catch of %s\n", item->u1.str); */ find_pval_gotos(item->u2.statements,lev+1); break; case PV_STATEMENTBLOCK: /* fields: item->u1.list == pval list of statements in block, one per entry in the list */ /* printf("Descending into statement block\n"); */ find_pval_gotos(item->u1.list,lev+1); break; case PV_GOTO: /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. item->u1.list->u1.str == where the data on a PV_WORD will always be. */ check_goto(item); /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */ break; case PV_INCLUDES: /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list */ for (p4=item->u1.list; p4; p4=p4->next) { /* for each context pointed to, find it, then find a context/label that matches the target here! */ char *incl_context = p4->u1.str; /* find a matching context name */ struct pval *that_context = find_context(incl_context); if (that_context && that_context->u2.statements) { /* printf("Descending into include of '%s' at line %d; that_context=%s, that_context type=%d\n", incl_context, item->startline, that_context->u1.str, that_context->type); */ find_pval_gotos(that_context->u2.statements,lev+1); /* keep working up the includes */ } } break; case PV_FOR: /* fields: item->u1.for_init == a string containing the initalizer item->u2.for_test == a string containing the loop test item->u3.for_inc == a string containing the loop increment item->u4.for_statements == a pval list of statements in the for () */ /* printf("Descending into for at line %d\n", item->startline); */ find_pval_gotos(item->u4.for_statements,lev+1); break; case PV_WHILE: /* fields: item->u1.str == the while conditional, as supplied by user item->u2.statements == a pval list of statements in the while () */ /* printf("Descending into while at line %d\n", item->startline); */ find_pval_gotos(item->u2.statements,lev+1); break; case PV_RANDOM: /* fields: item->u1.str == the random number expression, as supplied by user item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) fall thru to PV_IF */ case PV_IFTIME: /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) fall thru to PV_IF*/ case PV_IF: /* fields: item->u1.str == the if conditional, as supplied by user item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) */ /* printf("Descending into random/iftime/if at line %d\n", item->startline); */ find_pval_gotos(item->u2.statements,lev+1); if (item->u3.else_statements) { /* printf("Descending into random/iftime/if's ELSE at line %d\n", item->startline); */ find_pval_gotos(item->u3.else_statements,lev+1); } break; case PV_SWITCH: /* fields: item->u1.str == the switch expression item->u2.statements == a pval list of statements in the switch, (will be case statements, most likely!) */ /* printf("Descending into switch at line %d\n", item->startline); */ find_pval_gotos(item->u3.else_statements,lev+1); break; case PV_EXTENSION: /* fields: item->u1.str == the extension name, label, whatever it's called item->u2.statements == a pval list of statements in the extension item->u3.hints == a char * hint argument item->u4.regexten == an int boolean. non-zero says that regexten was specified */ /* printf("Descending into extension %s at line %d\n", item->u1.str, item->startline); */ find_pval_gotos(item->u2.statements,lev+1); break; default: break; }}static void find_pval_gotos(pval *item,int lev){ pval *i; for (i=item; i; i=i->next) { /* printf("About to call pval_goto_item, itemcount=%d, itemtype=%d\n", item_count, i->type); */ find_pval_goto_item(i, lev); }}/* general purpose label finder */static struct pval *match_pval_item(pval *item){ pval *x; switch ( item->type ) { case PV_MACRO: /* fields: item->u1.str == name of macro item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user item->u2.arglist->u1.str == argument item->u2.arglist->next == next arg item->u3.macro_statements == pval list of statements in macro body. */ /* printf(" matching in MACRO %s, match_context=%s; retoncontmtch=%d; \n", item->u1.str, match_context, return_on_context_match); */ if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { /* printf("MACRO: match context is: %s\n", match_context); */ if (return_on_context_match && !strcmp(item->u1.str, match_context)) /* if we're just searching for a context, don't bother descending into them */ { /* printf("Returning on matching macro %s\n", match_context); */ return item; } if (!return_on_context_match) { /* printf("Descending into matching macro %s/%s\n", match_context, item->u1.str); */ if ((x=match_pval(item->u3.macro_statements))) { /* printf("Responded with pval match %x\n", x); */ return x; } } } else { /* printf("Skipping context/macro %s\n", item->u1.str); */ } break; case PV_CONTEXT: /* fields: item->u1.str == name of context item->u2.statements == pval list of statements in context body item->u3.abstract == int 1 if an abstract keyword were present */ /* printf(" matching in CONTEXT\n"); */ if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { if (return_on_context_match && !strcmp(item->u1.str, match_context)) { /* printf("Returning on matching context %s\n", match_context); */ /* printf("non-CONTEXT: Responded with pval match %x\n", x); */ return item; } if (!return_on_context_match ) { /* printf("Descending into matching context %s\n", match_context); */ if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ { /* printf("CONTEXT: Responded with pval match %x\n", x); */ return x; } } } else { /* printf("Skipping context/macro %s\n", item->u1.str); */ } break; case PV_CASE: /* fields: item->u1.str == value of case item->u2.statements == pval list of statements under the case */ /* printf(" matching in CASE\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("CASE: Responded with pval match %x\n", x); */ return x; } break; case PV_PATTERN: /* fields: item->u1.str == value of case item->u2.statements == pval list of statements under the case */ /* printf(" matching in PATTERN\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("PATTERN: Responded with pval match %x\n", x); */ return x; } break; case PV_DEFAULT: /* fields: item->u2.statements == pval list of statements under the case */ /* printf(" matching in DEFAULT\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("DEFAULT: Responded with pval match %x\n", x); */ return x; } break; case PV_CATCH: /* fields: item->u1.str == name of extension to catch item->u2.statements == pval list of statements in context body */ /* printf(" matching in CATCH\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("CATCH: Responded with pval match %x\n", x); */ return x; } break; case PV_STATEMENTBLOCK: /* fields: item->u1.list == pval list of statements in block, one per entry in the list */ /* printf(" matching in STATEMENTBLOCK\n"); */ if ((x=match_pval(item->u1.list))) { /* printf("STATEMENTBLOCK: Responded with pval match %x\n", x); */ return x; } break; case PV_LABEL: /* fields: item->u1.str == label name */ /* printf("PV_LABEL %s (cont=%s, exten=%s\n", item->u1.str, current_context->u1.str, (current_extension?current_extension->u1.str:"<macro>"));*/ if (count_labels) { if (!strcmp(match_label, item->u1.str)) { label_count++; last_matched_label = item; } } else { if (!strcmp(match_label, item->u1.str)) { /* printf("LABEL: Responded with pval match %x\n", x); */ return item; } } break; case PV_FOR: /* fields: item->u1.for_init == a string containing the initalizer item->u2.for_test == a string containing the loop test item->u3.for_inc == a string containing the loop increment item->u4.for_statements == a pval list of statements in the for () */ /* printf(" matching in FOR\n"); */ if ((x=match_pval(item->u4.for_statements))) { /* printf("FOR: Responded with pval match %x\n", x);*/ return x; } break; case PV_WHILE: /* fields: item->u1.str == the while conditional, as supplied by user item->u2.statements == a pval list of statements in the while () */ /* printf(" matching in WHILE\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("WHILE: Responded with pval match %x\n", x); */ return x; } break; case PV_RANDOM: /* fields: item->u1.str == the random number expression, as supplied by user item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) fall thru to PV_IF */ case PV_IFTIME: /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) fall thru to PV_IF*/ case PV_IF: /* fields: item->u1.str == the if conditional, as supplied by user item->u2.statements == a pval list of statements in the if () item->u3.else_statements == a pval list of statements in the else (could be zero) */ /* printf(" matching in IF/IFTIME/RANDOM\n"); */ if ((x=match_pval(item->u2.statements))) { return x; } if (item->u3.else_statements) { if ((x=match_pval(item->u3.else_statements))) { /* printf("IF/IFTIME/RANDOM: Responded with pval match %x\n", x); */ return x; } } break; case PV_SWITCH: /* fields: item->u1.str == the switch expression item->u2.statements == a pval list of statements in the switch, (will be case statements, most likely!) */ /* printf(" matching in SWITCH\n"); */ if ((x=match_pval(item->u2.statements))) { /* printf("SWITCH: Responded with pval match %x\n", x); */ return x; } break; case PV_EXTENSION: /* fields: item->u1.str == the extension name, label, whatever it's called item->u2.statements == a pval list of statements in the extension item->u3.hints == a char * hint argument item->u4.regexten == an int boolean. non-zero says that regexten was specified */ /* printf(" matching in EXTENSION\n"); */ if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) { /* printf("Descending into matching exten %s => %s\n", match_exten, item->u1.str); */ if (strcmp(match_label,"1") == 0) { if (item->u2.statements) { struct pval *p5 = item->u2.statements; while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */ p5 = p5->next; if (p5) return p5; else return 0; } else return 0; } if ((x=match_pval(item->u2.statements))) { /* printf("EXTENSION: Responded with pval match %x\n", x); */ return x; } } else { /* printf("Skipping exten %s\n", item->u1.str); */ } break; default: /* printf(" matching in default = %d\n", item->type); */ break; } return 0;}struct pval *match_pval(pval *item){ pval *i; for (i=item; i; i=i->next) { pval *x; /* printf(" -- match pval: item %d\n", i->type); */ if ((x = match_pval_item(i))) { /* printf("match_pval: returning x=%x\n", (int)x); */ return x; /* cut the search short */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -