diff options
author | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-09-22 17:39:37 +0000 |
---|---|---|
committer | murf <murf@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-09-22 17:39:37 +0000 |
commit | 2451fd1ebfd2d4b6077038e52b2dfdde78d9c83c (patch) | |
tree | 5e2b505317d913665049866850d7717f5ac9656b /pbx | |
parent | fbcb44ca7cdb2e3f1a0524717340ae46e7e7f77c (diff) |
Merged revisions 83558 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r83558 | murf | 2007-09-22 10:41:43 -0600 (Sat, 22 Sep 2007) | 1 line
This closes issue #10788 -- the 3rd arg in the for statement is now wrapped in Set() only if there's an '=' in that string. Otherwise, if it begins with '&', then a Macro call is generated; otherwise it is made into an app call. A bit more accomodating, keeps the new guys happy, and the guys with ael-1 code should be happy, too
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@83575 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx')
-rw-r--r-- | pbx/pbx_ael.c | 769 |
1 files changed, 1 insertions, 768 deletions
diff --git a/pbx/pbx_ael.c b/pbx/pbx_ael.c index 39fe8ff20..8f4ae14cd 100644 --- a/pbx/pbx_ael.c +++ b/pbx/pbx_ael.c @@ -1,4 +1,4 @@ -/* +/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 2006, Digium, Inc. @@ -119,11 +119,8 @@ static void print_pval_list(FILE *fin, pval *item, int depth); static struct pval *find_label_in_current_extension(const char *label, pval *curr_ext); static struct pval *find_label_in_current_db(const char *context, const char *exten, const char *label); -static pval *get_goto_target(pval *item); -static int label_inside_case(pval *label); static pval *get_extension_or_contxt(pval *p); static pval *get_contxt(pval *p); -static void remove_spaces_before_equals(char *str); /* static void substitute_commas(char *str); */ #ifdef NOMORE /*! \brief I am adding this code to substitute commas with vertbars in the args to apps */ @@ -464,74 +461,6 @@ static struct pval *in_context(pval *item) } -static pval *get_goto_target(pval *item) -{ - /* just one item-- the label should be in the current extension */ - pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */ - pval *curr_cont; - - if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) { - struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext); - return x; - } - - curr_cont = get_contxt(item); - - /* TWO items */ - if (item->u1.list->next && !item->u1.list->next->next) { - if (!strstr((item->u1.list)->u1.str,"${") - && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ { - struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont); - return x; - } - } - - /* All 3 items! */ - if (item->u1.list->next && item->u1.list->next->next) { - /* all three */ - pval *first = item->u1.list; - pval *second = item->u1.list->next; - pval *third = item->u1.list->next->next; - - if (!strstr((item->u1.list)->u1.str,"${") - && !strstr(item->u1.list->next->u1.str,"${") - && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ { - struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); - if (!x) { - - struct pval *p3; - struct pval *that_context = find_context(item->u1.list->u1.str); - - /* the target of the goto could be in an included context!! Fancy that!! */ - /* look for includes in the current context */ - if (that_context) { - for (p3=that_context->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_other_context = find_context(incl_context); - if (that_other_context) { - struct pval *x3; - x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context); - if (x3) { - return x3; - } - } - } - } - } - } - } - return x; - } - } - return 0; -} - static void check_goto(pval *item) { /* check for the target of the goto-- does it exist? */ @@ -948,702 +877,6 @@ static struct pval *find_label_in_current_db(const char *context, const char *ex /* "CODE" GENERATOR -- Convert the AEL representation to asterisk extension language */ /* =============================================================================================== */ -static int control_statement_count = 0; - -static int label_inside_case(pval *label) -{ - pval *p = label; - - while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { - if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN ) { - return 1; - } - - p = p->dad; - } - return 0; -} - -static void linkexten(struct ael_extension *exten, struct ael_extension *add) -{ - add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */ - exten->next_exten = add; -} - -static void remove_spaces_before_equals(char *str) -{ - char *p; - while( str && *str && *str != '=' ) - { - if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' ) - { - p = str; - while( *p ) - { - *p = *(p+1); - p++; - } - } - else - str++; - } -} - -static void gen_match_to_pattern(char *pattern, char *result) -{ - /* the result will be a string that will be matched by pattern */ - char *p=pattern, *t=result; - while (*p) { - if (*p == 'x' || *p == 'n' || *p == 'z' || *p == 'X' || *p == 'N' || *p == 'Z') - *t++ = '9'; - else if (*p == '[') { - char *z = p+1; - while (*z != ']') - z++; - if (*(z+1)== ']') - z++; - *t++=*(p+1); /* use the first char in the set */ - p = z; - } else { - *t++ = *p; - } - p++; - } - *t++ = 0; /* cap it off */ -} - -static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context ) -{ - pval *p,*p2,*p3; - struct ael_priority *pr; - struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end; - struct ael_priority *while_test, *while_loop, *while_end; - struct ael_priority *switch_test, *switch_end, *fall_thru; - struct ael_priority *if_test, *if_end, *if_skip, *if_false; -#ifdef OLD_RAND_ACTION - struct ael_priority *rand_test, *rand_end, *rand_skip; -#endif - char buf1[2000]; - char buf2[2000]; - char *strp, *strp2; - char new_label[2000]; - int default_exists; - int local_control_statement_count; - int first; - struct ael_priority *loop_break_save; - struct ael_priority *loop_continue_save; - struct ael_extension *switch_case; - - for (p=statement; p; p=p->next) { - switch (p->type) { - case PV_VARDEC: - pr = new_prio(); - pr->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"%s=$[%s]", p->u1.str, p->u2.val); - pr->app = strdup("Set"); - remove_spaces_before_equals(buf1); - pr->appargs = strdup(buf1); - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_LOCALVARDEC: - pr = new_prio(); - pr->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"LOCAL(%s)=$[%s]", p->u1.str, p->u2.val); - pr->app = strdup("Set"); - remove_spaces_before_equals(buf1); - pr->appargs = strdup(buf1); - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_GOTO: - pr = new_prio(); - pr->type = AEL_APPCALL; - p->u2.goto_target = get_goto_target(p); - if( p->u2.goto_target ) { - p->u3.goto_target_in_case = p->u2.goto_target->u2.label_in_case = label_inside_case(p->u2.goto_target); - } - - if (!p->u1.list->next) /* just one */ { - pr->app = strdup("Goto"); - if (!mother_exten) - pr->appargs = strdup(p->u1.list->u1.str); - else { /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */ - snprintf(buf1,sizeof(buf1),"%s,%s", mother_exten->name, p->u1.list->u1.str); - pr->appargs = strdup(buf1); - } - - } else if (p->u1.list->next && !p->u1.list->next->next) /* two */ { - snprintf(buf1,sizeof(buf1),"%s,%s", p->u1.list->u1.str, p->u1.list->next->u1.str); - pr->app = strdup("Goto"); - pr->appargs = strdup(buf1); - } else if (p->u1.list->next && p->u1.list->next->next) { - snprintf(buf1,sizeof(buf1),"%s,%s,%s", p->u1.list->u1.str, - p->u1.list->next->u1.str, - p->u1.list->next->next->u1.str); - pr->app = strdup("Goto"); - pr->appargs = strdup(buf1); - } - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_LABEL: - pr = new_prio(); - pr->type = AEL_LABEL; - pr->origin = p; - p->u3.compiled_label = exten; - linkprio(exten, pr); - break; - - case PV_FOR: - control_statement_count++; - loop_break_save = exten->loop_break; /* save them, then restore before leaving */ - loop_continue_save = exten->loop_continue; - snprintf(new_label,sizeof(new_label),"for-%s-%d", label, control_statement_count); - for_init = new_prio(); - for_inc = new_prio(); - for_test = new_prio(); - for_loop = new_prio(); - for_end = new_prio(); - for_init->type = AEL_APPCALL; - for_inc->type = AEL_APPCALL; - for_test->type = AEL_FOR_CONTROL; - for_test->goto_false = for_end; - for_loop->type = AEL_CONTROL1; /* simple goto */ - for_end->type = AEL_APPCALL; - for_init->app = strdup("Set"); - - strcpy(buf2,p->u1.for_init); - remove_spaces_before_equals(buf2); - strp = strchr(buf2, '='); - strp2 = strchr(p->u1.for_init, '='); - if (strp) { - *(strp+1) = 0; - strcat(buf2,"$["); - strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2); - strcat(buf2,"]"); - for_init->appargs = strdup(buf2); - } else - for_init->appargs = strdup(p->u1.for_init); - - for_inc->app = strdup("Set"); - - strcpy(buf2,p->u3.for_inc); - remove_spaces_before_equals(buf2); - strp = strchr(buf2, '='); - strp2 = strchr(p->u3.for_inc, '='); - if (strp) { - *(strp+1) = 0; - strcat(buf2,"$["); - strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2); - strcat(buf2,"]"); - for_inc->appargs = strdup(buf2); - } else - for_inc->appargs = strdup(p->u3.for_inc); - snprintf(buf1,sizeof(buf1),"$[%s]",p->u2.for_test); - for_test->app = 0; - for_test->appargs = strdup(buf1); - for_loop->goto_true = for_test; - snprintf(buf1,sizeof(buf1),"Finish for-%s-%d", label, control_statement_count); - for_end->app = strdup("NoOp"); - for_end->appargs = strdup(buf1); - /* link & load! */ - linkprio(exten, for_init); - linkprio(exten, for_test); - - /* now, put the body of the for loop here */ - exten->loop_break = for_end; - exten->loop_continue = for_inc; - - gen_prios(exten, new_label, p->u4.for_statements, mother_exten, this_context); /* this will link in all the statements here */ - - linkprio(exten, for_inc); - linkprio(exten, for_loop); - linkprio(exten, for_end); - - - exten->loop_break = loop_break_save; - exten->loop_continue = loop_continue_save; - for_loop->origin = p; - break; - - case PV_WHILE: - control_statement_count++; - loop_break_save = exten->loop_break; /* save them, then restore before leaving */ - loop_continue_save = exten->loop_continue; - snprintf(new_label,sizeof(new_label),"while-%s-%d", label, control_statement_count); - while_test = new_prio(); - while_loop = new_prio(); - while_end = new_prio(); - while_test->type = AEL_FOR_CONTROL; - while_test->goto_false = while_end; - while_loop->type = AEL_CONTROL1; /* simple goto */ - while_end->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str); - while_test->app = 0; - while_test->appargs = strdup(buf1); - while_loop->goto_true = while_test; - snprintf(buf1,sizeof(buf1),"Finish while-%s-%d", label, control_statement_count); - while_end->app = strdup("NoOp"); - while_end->appargs = strdup(buf1); - - linkprio(exten, while_test); - - /* now, put the body of the for loop here */ - exten->loop_break = while_end; - exten->loop_continue = while_test; - - gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the while body statements here */ - - linkprio(exten, while_loop); - linkprio(exten, while_end); - - - exten->loop_break = loop_break_save; - exten->loop_continue = loop_continue_save; - while_loop->origin = p; - break; - - case PV_SWITCH: - control_statement_count++; - local_control_statement_count = control_statement_count; - loop_break_save = exten->loop_break; /* save them, then restore before leaving */ - loop_continue_save = exten->loop_continue; - snprintf(new_label,sizeof(new_label),"sw-%s-%d", label, control_statement_count); - - switch_test = new_prio(); - switch_end = new_prio(); - switch_test->type = AEL_APPCALL; - switch_end->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",control_statement_count, p->u1.str); - switch_test->app = strdup("Goto"); - switch_test->appargs = strdup(buf1); - snprintf(buf1,sizeof(buf1),"Finish switch-%s-%d", label, control_statement_count); - switch_end->app = strdup("NoOp"); - switch_end->appargs = strdup(buf1); - switch_end->origin = p; - switch_end->exten = exten; - - linkprio(exten, switch_test); - linkprio(exten, switch_end); - - exten->loop_break = switch_end; - exten->loop_continue = 0; - default_exists = 0; - - for (p2=p->u2.statements; p2; p2=p2->next) { - /* now, for each case/default put the body of the for loop here */ - if (p2->type == PV_CASE) { - /* ok, generate a extension and link it in */ - switch_case = new_exten(); - switch_case->context = this_context; - switch_case->is_switch = 1; - /* the break/continue locations are inherited from parent */ - switch_case->loop_break = exten->loop_break; - switch_case->loop_continue = exten->loop_continue; - - linkexten(exten,switch_case); - snprintf(buf1,sizeof(buf1),"sw-%d-%s", local_control_statement_count, p2->u1.str); - switch_case->name = strdup(buf1); - snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, local_control_statement_count); - - gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the case body statements here */ - - /* here is where we write code to "fall thru" to the next case... if there is one... */ - for (p3=p2->u2.statements; p3; p3=p3->next) { - if (!p3->next) - break; - } - /* p3 now points the last statement... */ - if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) { - /* is there a following CASE/PATTERN/DEFAULT? */ - if (p2->next && p2->next->type == PV_CASE) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_PATTERN) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - gen_match_to_pattern(p2->next->u1.str, buf2); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10", local_control_statement_count, buf2); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_DEFAULT) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (!p2->next) { - fall_thru = new_prio(); - fall_thru->type = AEL_CONTROL1; - fall_thru->goto_true = switch_end; - fall_thru->app = strdup("Goto"); - linkprio(switch_case, fall_thru); - } - } - if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ - char buf[2000]; - struct ael_priority *np2 = new_prio(); - np2->type = AEL_APPCALL; - np2->app = strdup("NoOp"); - snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); - np2->appargs = strdup(buf); - linkprio(switch_case, np2); - switch_case-> return_target = np2; - } - } else if (p2->type == PV_PATTERN) { - /* ok, generate a extension and link it in */ - switch_case = new_exten(); - switch_case->context = this_context; - switch_case->is_switch = 1; - /* the break/continue locations are inherited from parent */ - switch_case->loop_break = exten->loop_break; - switch_case->loop_continue = exten->loop_continue; - - linkexten(exten,switch_case); - snprintf(buf1,sizeof(buf1),"_sw-%d-%s", local_control_statement_count, p2->u1.str); - switch_case->name = strdup(buf1); - snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, local_control_statement_count); - - gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the while body statements here */ - /* here is where we write code to "fall thru" to the next case... if there is one... */ - for (p3=p2->u2.statements; p3; p3=p3->next) { - if (!p3->next) - break; - } - /* p3 now points the last statement... */ - if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { - /* is there a following CASE/PATTERN/DEFAULT? */ - if (p2->next && p2->next->type == PV_CASE) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_PATTERN) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - gen_match_to_pattern(p2->next->u1.str, buf2); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, buf2); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_DEFAULT) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (!p2->next) { - fall_thru = new_prio(); - fall_thru->type = AEL_CONTROL1; - fall_thru->goto_true = switch_end; - fall_thru->app = strdup("Goto"); - linkprio(switch_case, fall_thru); - } - } - if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ - char buf[2000]; - struct ael_priority *np2 = new_prio(); - np2->type = AEL_APPCALL; - np2->app = strdup("NoOp"); - snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); - np2->appargs = strdup(buf); - linkprio(switch_case, np2); - switch_case-> return_target = np2; - } - } else if (p2->type == PV_DEFAULT) { - default_exists++; - /* ok, generate a extension and link it in */ - switch_case = new_exten(); - switch_case->context = this_context; - switch_case->is_switch = 1; - /* the break/continue locations are inherited from parent */ - switch_case->loop_break = exten->loop_break; - switch_case->loop_continue = exten->loop_continue; - linkexten(exten,switch_case); - snprintf(buf1,sizeof(buf1),"_sw-%d-.", local_control_statement_count); - switch_case->name = strdup(buf1); - - snprintf(new_label,sizeof(new_label),"sw-%s-default-%d", label, local_control_statement_count); - - gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the while body statements here */ - - /* here is where we write code to "fall thru" to the next case... if there is one... */ - for (p3=p2->u2.statements; p3; p3=p3->next) { - if (!p3->next) - break; - } - /* p3 now points the last statement... */ - if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { - /* is there a following CASE/PATTERN/DEFAULT? */ - if (p2->next && p2->next->type == PV_CASE) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_PATTERN) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - gen_match_to_pattern(p2->next->u1.str, buf2); - snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, buf2); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (p2->next && p2->next->type == PV_DEFAULT) { - fall_thru = new_prio(); - fall_thru->type = AEL_APPCALL; - fall_thru->app = strdup("Goto"); - snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); - fall_thru->appargs = strdup(buf1); - linkprio(switch_case, fall_thru); - } else if (!p2->next) { - fall_thru = new_prio(); - fall_thru->type = AEL_CONTROL1; - fall_thru->goto_true = switch_end; - fall_thru->app = strdup("Goto"); - linkprio(switch_case, fall_thru); - } - } - if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ - char buf[2000]; - struct ael_priority *np2 = new_prio(); - np2->type = AEL_APPCALL; - np2->app = strdup("NoOp"); - snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); - np2->appargs = strdup(buf); - linkprio(switch_case, np2); - switch_case-> return_target = np2; - } - } else { - /* what could it be??? */ - } - } - - exten->loop_break = loop_break_save; - exten->loop_continue = loop_continue_save; - switch_test->origin = p; - switch_end->origin = p; - break; - - case PV_MACRO_CALL: - pr = new_prio(); - pr->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"%s,s,1", p->u1.str); - first = 1; - for (p2 = p->u2.arglist; p2; p2 = p2->next) { - if (first) - { - strcat(buf1,"("); - first = 0; - } - else - strcat(buf1,","); - strcat(buf1,p2->u1.str); - } - if (!first) - strcat(buf1,")"); - - pr->app = strdup("Gosub"); - pr->appargs = strdup(buf1); - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_APPLICATION_CALL: - pr = new_prio(); - pr->type = AEL_APPCALL; - buf1[0] = 0; - for (p2 = p->u2.arglist; p2; p2 = p2->next) { - if (p2 != p->u2.arglist ) - strcat(buf1,","); - /*substitute_commas(p2->u1.str); */ - strcat(buf1,p2->u1.str); - } - pr->app = strdup(p->u1.str); - pr->appargs = strdup(buf1); - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_BREAK: - pr = new_prio(); - pr->type = AEL_CONTROL1; /* simple goto */ - pr->goto_true = exten->loop_break; - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_RETURN: /* hmmmm */ - pr = new_prio(); - pr->type = AEL_RETURN; /* simple Return */ - /* exten->return_needed++; */ - pr->app = strdup("Return"); - pr->appargs = strdup(""); - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_CONTINUE: - pr = new_prio(); - pr->type = AEL_CONTROL1; /* simple goto */ - pr->goto_true = exten->loop_continue; - pr->origin = p; - linkprio(exten, pr); - break; - - case PV_IFTIME: - control_statement_count++; - snprintf(new_label,sizeof(new_label),"iftime-%s-%d", label, control_statement_count); - - if_test = new_prio(); - if_test->type = AEL_IFTIME_CONTROL; - snprintf(buf1,sizeof(buf1),"%s,%s,%s,%s", - p->u1.list->u1.str, - p->u1.list->next->u1.str, - p->u1.list->next->next->u1.str, - p->u1.list->next->next->next->u1.str); - if_test->app = 0; - if_test->appargs = strdup(buf1); - if_test->origin = p; - - if_end = new_prio(); - if_end->type = AEL_APPCALL; - snprintf(buf1,sizeof(buf1),"Finish iftime-%s-%d", label, control_statement_count); - if_end->app = strdup("NoOp"); - if_end->appargs = strdup(buf1); - - if (p->u3.else_statements) { - if_skip = new_prio(); - if_skip->type = AEL_CONTROL1; /* simple goto */ - if_skip->goto_true = if_end; - if_skip->origin = p; - - } else { - if_skip = 0; - - if_test->goto_false = if_end; - } - - if_false = new_prio(); - if_false->type = AEL_CONTROL1; - if (p->u3.else_statements) { - if_false->goto_true = if_skip; /* +1 */ - } else { - if_false->goto_true = if_end; - } - - /* link & load! */ - linkprio(exten, if_test); - linkprio(exten, if_false); - - /* now, put the body of the if here */ - - gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */ - - if (p->u3.else_statements) { - linkprio(exten, if_skip); - gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */ - - } - - linkprio(exten, if_end); - - break; - - case PV_RANDOM: - case PV_IF: - control_statement_count++; - snprintf(new_label,sizeof(new_label),"if-%s-%d", label, control_statement_count); - - if_test = new_prio(); - if_end = new_prio(); - if_test->type = AEL_IF_CONTROL; - if_end->type = AEL_APPCALL; - if ( p->type == PV_RANDOM ) - snprintf(buf1,sizeof(buf1),"$[${RAND(0,99)} < (%s)]",p->u1.str); - else - snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str); - if_test->app = 0; - if_test->appargs = strdup(buf1); - snprintf(buf1,sizeof(buf1),"Finish if-%s-%d", label, control_statement_count); - if_end->app = strdup("NoOp"); - if_end->appargs = strdup(buf1); - if_test->origin = p; - - if (p->u3.else_statements) { - if_skip = new_prio(); - if_skip->type = AEL_CONTROL1; /* simple goto */ - if_skip->goto_true = if_end; - if_test->goto_false = if_skip;; - } else { - if_skip = 0; - if_test->goto_false = if_end;; - } - - /* link & load! */ - linkprio(exten, if_test); - - /* now, put the body of the if here */ - - gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */ - - if (p->u3.else_statements) { - linkprio(exten, if_skip); - gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */ - - } - - linkprio(exten, if_end); - - break; - - case PV_STATEMENTBLOCK: - gen_prios(exten, label, p->u1.list, mother_exten, this_context ); /* recurse into the block */ - break; - - case PV_CATCH: - control_statement_count++; - /* generate an extension with name of catch, put all catch stats - into this exten! */ - switch_case = new_exten(); - switch_case->context = this_context; - linkexten(exten,switch_case); - switch_case->name = strdup(p->u1.str); - snprintf(new_label,sizeof(new_label),"catch-%s-%d",p->u1.str, control_statement_count); - - gen_prios(switch_case, new_label, p->u2.statements,mother_exten,this_context); /* this will link in all the catch body statements here */ - if (switch_case->return_needed) { /* returns now generate a Return() app call, no longer a goto to the end of the exten */ - char buf[2000]; - struct ael_priority *np2 = new_prio(); - np2->type = AEL_APPCALL; - np2->app = strdup("NoOp"); - snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); - np2->appargs = strdup(buf); - linkprio(switch_case, np2); - switch_case-> return_target = np2; - } - - break; - default: - break; - } - } -} - static pval *get_extension_or_contxt(pval *p) { while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) { |