📄 pval.c
字号:
case PV_PATTERN: /* fields: item->u1.str == value of case item->u2.statements == pval list of statements under the case */ traverse_pval_item_template(item->u2.statements,depth+1); break; case PV_DEFAULT: /* fields: item->u2.statements == pval list of statements under the case */ traverse_pval_item_template(item->u2.statements,depth+1); break; case PV_CATCH: /* fields: item->u1.str == name of extension to catch item->u2.statements == pval list of statements in context body */ traverse_pval_item_template(item->u2.statements,depth+1); break; case PV_SWITCHES: /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list */ traverse_pval_item_template(item->u1.list,depth+1); break; case PV_ESWITCHES: /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list */ traverse_pval_item_template(item->u1.list,depth+1); break; case PV_INCLUDES: /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list item->u2.arglist == pval list of 4 PV_WORD elements for time values */ traverse_pval_item_template(item->u1.list,depth+1); traverse_pval_item_template(item->u2.arglist,depth+1); break; case PV_STATEMENTBLOCK: /* fields: item->u1.list == pval list of statements in block, one per entry in the list */ traverse_pval_item_template(item->u1.list,depth+1); break; case PV_LOCALVARDEC: case PV_VARDEC: /* fields: item->u1.str == variable name item->u2.val == variable value to assign */ 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. */ if ( item->u1.list->next ) ; if ( item->u1.list->next && item->u1.list->next->next ) ; break; case PV_LABEL: /* fields: item->u1.str == label name */ 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 () */ traverse_pval_item_template(item->u4.for_statements,depth+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 () */ traverse_pval_item_template(item->u2.statements,depth+1); break; case PV_BREAK: /* fields: none */ break; case PV_RETURN: /* fields: none */ break; case PV_CONTINUE: /* fields: none */ break; case PV_IFTIME: /* fields: item->u1.list == there are 4 linked PV_WORDs here. 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) */ traverse_pval_item_template(item->u2.statements,depth+1); if ( item->u3.else_statements ) { traverse_pval_item_template(item->u3.else_statements,depth+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) */ traverse_pval_item_template(item->u2.statements,depth+1); if ( item->u3.else_statements ) { traverse_pval_item_template(item->u3.else_statements,depth+1); } break; 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) */ traverse_pval_item_template(item->u2.statements,depth+1); if ( item->u3.else_statements ) { traverse_pval_item_template(item->u3.else_statements,depth+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!) */ traverse_pval_item_template(item->u2.statements,depth+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 */ traverse_pval_item_template(item->u2.statements,depth+1); break; case PV_IGNOREPAT: /* fields: item->u1.str == the ignorepat data */ break; case PV_GLOBALS: /* fields: item->u1.statements == pval list of statements, usually vardecs */ traverse_pval_item_template(item->u1.statements,depth+1); break; }}void traverse_pval_template(pval *item, int depth) /* depth comes in handy for a pretty print (indentation), but you may not need it */{ pval *i; for (i=item; i; i=i->next) { traverse_pval_item_template(i, depth); }}/* SEMANTIC CHECKING FOR AEL: ============================================================================= *//* (not all that is syntactically legal is good! */static void check_macro_returns(pval *macro){ pval *i; if (!macro->u3.macro_statements) { pval *z = calloc(1, sizeof(struct pval)); ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n", macro->filename, macro->startline, macro->endline, macro->u1.str); z->type = PV_RETURN; z->startline = macro->startline; z->endline = macro->endline; z->startcol = macro->startcol; z->endcol = macro->endcol; z->filename = strdup(macro->filename); macro->u3.macro_statements = z; return; } for (i=macro->u3.macro_statements; i; i=i->next) { /* if the last statement in the list is not return, then insert a return there */ if (i->next == NULL) { if (i->type != PV_RETURN) { pval *z = calloc(1, sizeof(struct pval)); ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n", macro->filename, macro->startline, macro->endline, macro->u1.str); z->type = PV_RETURN; z->startline = macro->startline; z->endline = macro->endline; z->startcol = macro->startcol; z->endcol = macro->endcol; z->filename = strdup(macro->filename); i->next = z; return; } } } return;}static int extension_matches(pval *here, const char *exten, const char *pattern){ int err1; regex_t preg; /* simple case, they match exactly, the pattern and exten name */ if (strcmp(pattern,exten) == 0) return 1; if (pattern[0] == '_') { char reg1[2000]; const char *p; char *r = reg1; if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ { ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n", pattern); return 0; } /* form a regular expression from the pattern, and then match it against exten */ *r++ = '^'; /* what if the extension is a pattern ?? */ *r++ = '_'; /* what if the extension is a pattern ?? */ *r++ = '?'; for (p=pattern+1; *p; p++) { switch ( *p ) { case 'X': *r++ = '['; *r++ = '0'; *r++ = '-'; *r++ = '9'; *r++ = 'X'; *r++ = ']'; break; case 'Z': *r++ = '['; *r++ = '1'; *r++ = '-'; *r++ = '9'; *r++ = 'Z'; *r++ = ']'; break; case 'N': *r++ = '['; *r++ = '2'; *r++ = '-'; *r++ = '9'; *r++ = 'N'; *r++ = ']'; break; case '[': while ( *p && *p != ']' ) { *r++ = *p++; } *r++ = ']'; if ( *p != ']') { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n", here->filename, here->startline, here->endline, pattern); } break; case '.': case '!': *r++ = '.'; *r++ = '*'; break; case '*': *r++ = '\\'; *r++ = '*'; break; default: *r++ = *p; break; } } *r++ = '$'; /* what if the extension is a pattern ?? */ *r++ = *p++; /* put in the closing null */ err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED); if ( err1 ) { char errmess[500]; regerror(err1,&preg,errmess,sizeof(errmess)); regfree(&preg); ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n", reg1, err1); return 0; } err1 = regexec(&preg, exten, 0, 0, 0); regfree(&preg); if ( err1 ) { /* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n", err1,exten, pattern, reg1); */ return 0; /* no match */ } else { /* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n", exten, pattern); */ return 1; } } else { if ( strcmp(exten,pattern) == 0 ) { return 1; } else return 0; }}static void check_expr2_input(pval *expr, char *str){ int spaces = strspn(str,"\t \n"); if ( !strncmp(str+spaces,"$[",2) ) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n", expr->filename, expr->startline, expr->endline, str); warns++; }}static void check_includes(pval *includes){ struct pval *p4; for (p4=includes->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_other_context = find_context(incl_context); if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\ (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n", includes->filename, includes->startline, includes->endline, incl_context, incl_context); warns++; } }}static void check_timerange(pval *p){ char *times; char *e; int s1, s2; int e1, e2; times = ast_strdupa(p->u1.str); /* Star is all times */ if (ast_strlen_zero(times) || !strcmp(times, "*")) { return; } /* Otherwise expect a range */ e = strchr(times, '-'); if (!e) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) requires a '-' surrounded by two 24-hour times of day!\n", p->filename, p->startline, p->endline, times); warns++; return; } *e = '\0'; e++; while (*e && !isdigit(*e)) e++; if (!*e) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n", p->filename, p->startline, p->endline, p->u1.str); warns++; } if (sscanf(times, "%d:%d", &s1, &s2) != 2) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n", p->filename, p->startline, p->endline, times); warns++; } if (sscanf(e, "%d:%d", &e1, &e2) != 2) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n", p->filename, p->startline, p->endline, times); warns++; } s1 = s1 * 30 + s2/2; if ((s1 < 0) || (s1 >= 24*30)) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n", p->filename, p->startline, p->endline, times); warns++; } e1 = e1 * 30 + e2/2; if ((e1 < 0) || (e1 >= 24*30)) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n", p->filename, p->startline, p->endline, e); warns++; } return;}static char *days[] ={ "sun", "mon", "tue", "wed", "thu", "fri", "sat",};/*! \brief get_dow: Get day of week */static void check_dow(pval *DOW){ char *dow; char *c; /* The following line is coincidence, really! */ int s, e; dow = ast_strdupa(DOW->u1.str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -