📄 pval.c
字号:
} } return 0;}#if 0int count_labels_in_current_context(char *label){ label_count = 0; count_labels = 1; return_on_context_match = 0; match_pval(current_context->u2.statements); return label_count;}#endifstruct pval *find_first_label_in_current_context(char *label, pval *curr_cont){ /* printf(" --- Got args %s, %s\n", exten, label); */ struct pval *ret; struct pval *p3; count_labels = 0; return_on_context_match = 0; match_context = "*"; match_exten = "*"; match_label = label; ret = match_pval(curr_cont); if (ret) return ret; /* the target of the goto could be in an included context!! Fancy that!! */ /* look for includes in the current context */ for (p3=curr_cont->u2.statements; p3; p3=p3->next) { if (p3->type == PV_INCLUDES) { struct pval *p4; for (p4=p3->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) { struct pval *x3; x3 = find_first_label_in_current_context(label, that_context); if (x3) { return x3; } } } } } return 0;}struct pval *find_label_in_current_context(char *exten, char *label, pval *curr_cont){ /* printf(" --- Got args %s, %s\n", exten, label); */ struct pval *ret; struct pval *p3; count_labels = 0; return_on_context_match = 0; match_context = "*"; match_exten = exten; match_label = label; ret = match_pval(curr_cont->u2.statements); if (ret) return ret; /* the target of the goto could be in an included context!! Fancy that!! */ /* look for includes in the current context */ for (p3=curr_cont->u2.statements; p3; p3=p3->next) { if (p3->type == PV_INCLUDES) { struct pval *p4; for (p4=p3->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) { struct pval *x3; x3 = find_label_in_current_context(exten, label, that_context); if (x3) { return x3; } } } } } return 0;}static struct pval *find_label_in_current_extension(const char *label, pval *curr_ext){ /* printf(" --- Got args %s\n", label); */ count_labels = 0; return_on_context_match = 0; match_context = "*"; match_exten = "*"; match_label = label; return match_pval(curr_ext);}static struct pval *find_label_in_current_db(const char *context, const char *exten, const char *label){ /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */ count_labels = 0; return_on_context_match = 0; match_context = context; match_exten = exten; match_label = label; return match_pval(current_db);}struct pval *find_macro(char *name){ return_on_context_match = 1; count_labels = 0; match_context = name; match_exten = "*"; /* don't really need to set these, shouldn't be reached */ match_label = "*"; return match_pval(current_db);}struct pval *find_context(char *name){ return_on_context_match = 1; count_labels = 0; match_context = name; match_exten = "*"; /* don't really need to set these, shouldn't be reached */ match_label = "*"; return match_pval(current_db);}int is_float(char *arg ){ char *s; for (s=arg; *s; s++) { if (*s != '.' && (*s < '0' || *s > '9')) return 0; } return 1;}int is_int(char *arg ){ char *s; for (s=arg; *s; s++) { if (*s < '0' || *s > '9') return 0; } return 1;}int is_empty(char *arg){ if (!arg) return 1; if (*arg == 0) return 1; while (*arg) { if (*arg != ' ' && *arg != '\t') return 0; arg++; } return 1;}#ifdef AAL_ARGCHECKint option_matches_j( struct argdesc *should, pval *is, struct argapp *app){ struct argchoice *ac; char *opcop,*q,*p; switch (should->dtype) { case ARGD_OPTIONSET: if ( strstr(is->u1.str,"${") ) return 0; /* no checking anything if there's a var reference in there! */ opcop = ast_strdupa(is->u1.str); for (q=opcop;*q;q++) { /* erase the innards of X(innard) type arguments, so we don't get confused later */ if ( *q == '(' ) { p = q+1; while (*p && *p != ')' ) *p++ = '+'; q = p+1; } } for (ac=app->opts; ac; ac=ac->next) { if (strlen(ac->name)>1 && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */ return 0; } for (ac=app->opts; ac; ac=ac->next) { if (strlen(ac->name)==1 || strchr(ac->name,'(')) { char *p = strchr(opcop,ac->name[0]); /* wipe out all matched options in the user-supplied string */ if (p && *p == 'j') { ast_log(LOG_ERROR, "Error: file %s, line %d-%d: The j option in the %s application call is not appropriate for AEL!\n", is->filename, is->startline, is->endline, app->name); errs++; } if (p) { *p = '+'; if (ac->name[1] == '(') { if (*(p+1) != '(') { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call should have an (argument), but doesn't!\n", is->filename, is->startline, is->endline, ac->name[0], app->name); warns++; } } } } } for (q=opcop; *q; q++) { if ( *q != '+' && *q != '(' && *q != ')') { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The %c option in the %s application call is not available as an option!\n", is->filename, is->startline, is->endline, *q, app->name); warns++; } } return 1; break; default: return 0; } }int option_matches( struct argdesc *should, pval *is, struct argapp *app){ struct argchoice *ac; char *opcop; switch (should->dtype) { case ARGD_STRING: if (is_empty(is->u1.str) && should->type == ARGD_REQUIRED) return 0; if (is->u1.str && strlen(is->u1.str) > 0) /* most will match */ return 1; break; case ARGD_INT: if (is_int(is->u1.str)) return 1; else return 0; break; case ARGD_FLOAT: if (is_float(is->u1.str)) return 1; else return 0; break; case ARGD_ENUM: if( !is->u1.str || strlen(is->u1.str) == 0 ) return 1; /* a null arg in the call will match an enum, I guess! */ for (ac=should->choices; ac; ac=ac->next) { if (strcmp(ac->name,is->u1.str) == 0) return 1; } return 0; break; case ARGD_OPTIONSET: opcop = ast_strdupa(is->u1.str); for (ac=app->opts; ac; ac=ac->next) { if (strlen(ac->name)>1 && strchr(ac->name,'(') == 0 && strcmp(ac->name,is->u1.str) == 0) /* multichar option, no parens, and a match? */ return 1; } for (ac=app->opts; ac; ac=ac->next) { if (strlen(ac->name)==1 || strchr(ac->name,'(')) { char *p = strchr(opcop,ac->name[0]); /* wipe out all matched options in the user-supplied string */ if (p) { *p = '+'; if (ac->name[1] == '(') { if (*(p+1) == '(') { char *q = p+1; while (*q && *q != ')') { *q++ = '+'; } *q = '+'; } } } } } return 1; break; case ARGD_VARARG: return 1; /* matches anything */ break; } return 1; /* unless some for-sure match or non-match returns, then it must be close enough ... */}#endifint check_app_args(pval* appcall, pval *arglist, struct argapp *app){#ifdef AAL_ARGCHECK struct argdesc *ad = app->args; pval *pa; int z; for (pa = arglist; pa; pa=pa->next) { if (!ad) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n", arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name); warns++; return 1; } else { /* find the first entry in the ad list that will match */ do { if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */ break; z= option_matches( ad, pa, app); if (!z) { if ( !arglist ) arglist=appcall; if (ad->type == ARGD_REQUIRED) { ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); warns++; return 1; } } else if (z && ad->dtype == ARGD_OPTIONSET) { option_matches_j( ad, pa, app); } ad = ad->next; } while (ad && !z); } } /* any app nodes left, that are not optional? */ for ( ; ad; ad=ad->next) { if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) { if ( !arglist ) arglist=appcall; ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); warns++; return 1; } } return 0;#else return 0;#endif}void check_switch_expr(pval *item, struct argapp *apps){#ifdef AAL_ARGCHECK /* get and clean the variable name */ char *buff1, *p; struct argapp *a,*a2; struct appsetvar *v,*v2; struct argchoice *c; pval *t; p = item->u1.str; while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) ) p++; buff1 = ast_strdupa(p); while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t')) buff1[strlen(buff1)-1] = 0; /* buff1 now contains the variable name */ v = 0; for (a=apps; a; a=a->next) { for (v=a->setvars;v;v=v->next) { if (strcmp(v->name,buff1) == 0) { break; } } if ( v ) break; } if (v && v->vals) { /* we have a match, to a variable that has a set of determined values */ int def= 0; int pat = 0; int f1 = 0; /* first of all, does this switch have a default case ? */ for (t=item->u2.statements; t; t=t->next) { if (t->type == PV_DEFAULT) { def =1; break; } if (t->type == PV_PATTERN) { pat++; } } if (def || pat) /* nothing to check. All cases accounted for! */ return; for (c=v->vals; c; c=c->next) { f1 = 0; for (t=item->u2.statements; t; t=t->next) { if (t->type == PV_CASE || t->type == PV_PATTERN) { if (!strcmp(t->u1.str,c->name)) { f1 = 1; break; } } } if (!f1) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n", item->filename, item->startline, item->endline, item->u1.str, c->name); warns++; } } /* next, is there an app call in the current exten, that would set this var? */ f1 = 0; t = current_extension->u2.statements; if ( t && t->type == PV_STATEMENTBLOCK ) t = t->u1.statements; for (; t && t != item; t=t->next) { if (t->type == PV_APPLICATION_CALL) { /* find the application that matches the u1.str */ for (a2=apps; a2; a2=a2->next) { if (strcasecmp(a2->name, t->u1.str)==0) { for (v2=a2->setvars; v2; v2=v2->next) { if (strcmp(v2->name, buff1) == 0) { /* found an app that sets the var */ f1 = 1; break; } } } if (f1) break; } } if (f1) break; } /* see if it sets the var */ if (!f1) { ast_log(LOG_WAR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -