[asterisk-commits] tilghman: trunk r222273 - /trunk/res/ael/pval.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 6 14:17:13 CDT 2009


Author: tilghman
Date: Tue Oct  6 14:17:11 2009
New Revision: 222273

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=222273
Log:
When we call a gosub routine, the variables should be scoped to avoid contaminating the caller.
This affected the ~~EXTEN~~ hack, where a subroutine might have changed the
value before it was used in the caller.
Patch by myself, tested by ebroad on #asterisk

Modified:
    trunk/res/ael/pval.c

Modified: trunk/res/ael/pval.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/ael/pval.c?view=diff&rev=222273&r1=222272&r2=222273
==============================================================================
--- trunk/res/ael/pval.c (original)
+++ trunk/res/ael/pval.c Tue Oct  6 14:17:11 2009
@@ -3361,38 +3361,60 @@
 		if (contains_switch(statement)) { /* only run contains_switch if you haven't checked before */
 			if (mother_exten) {
 				if (!mother_exten->has_switch) {
-					switch_set = new_prio();
-					switch_set->type = AEL_APPCALL;
-					if (!ast_compat_app_set) {
-						switch_set->app = strdup("MSet");
-					} else {
-						switch_set->app = strdup("Set");
-					}
-					switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
-					linkprio(exten, switch_set, mother_exten);
-					mother_exten->has_switch = 1;
-					mother_exten->checked_switch = 1;
-					if (exten) {
-						exten->has_switch = 1;
-						exten->checked_switch = 1;
+					for (first = 1; first >= 0; first--) {
+						switch_set = new_prio();
+						switch_set->type = AEL_APPCALL;
+						if (!ast_compat_app_set) {
+							switch_set->app = strdup("MSet");
+						} else {
+							switch_set->app = strdup("Set");
+						}
+						/* Are we likely inside a gosub subroutine? */
+						if (!strcmp(mother_exten->name, "s") && first) {
+							/* If we're not actually within a gosub, this will fail, but the
+							 * second time through, it will get set.  If we are within gosub,
+							 * the second time through is redundant, but acceptable. */
+							switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
+						} else {
+							switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
+							first = 0;
+						}
+						linkprio(exten, switch_set, mother_exten);
+						mother_exten->has_switch = 1;
+						mother_exten->checked_switch = 1;
+						if (exten) {
+							exten->has_switch = 1;
+							exten->checked_switch = 1;
+						}
 					}
 				}
 			} else if (exten) {
 				if (!exten->has_switch) {
-					switch_set = new_prio();
-					switch_set->type = AEL_APPCALL;
-					if (!ast_compat_app_set) {
-						switch_set->app = strdup("MSet");
-					} else {
-						switch_set->app = strdup("Set");
-					}
-					switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
-					linkprio(exten, switch_set, mother_exten);
-					exten->has_switch = 1;
-					exten->checked_switch = 1;
-					if (mother_exten) {
-						mother_exten->has_switch = 1;
-						mother_exten->checked_switch = 1;
+					for (first = 1; first >= 0; first--) {
+						switch_set = new_prio();
+						switch_set->type = AEL_APPCALL;
+						if (!ast_compat_app_set) {
+							switch_set->app = strdup("MSet");
+						} else {
+							switch_set->app = strdup("Set");
+						}
+						/* Are we likely inside a gosub subroutine? */
+						if (!strcmp(exten->name, "s")) {
+							/* If we're not actually within a gosub, this will fail, but the
+							 * second time through, it will get set.  If we are within gosub,
+							 * the second time through is redundant, but acceptable. */
+							switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
+						} else {
+							switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
+							first = 0;
+						}
+						linkprio(exten, switch_set, mother_exten);
+						exten->has_switch = 1;
+						exten->checked_switch = 1;
+						if (mother_exten) {
+							mother_exten->has_switch = 1;
+							mother_exten->checked_switch = 1;
+						}
 					}
 				}
 			}




More information about the asterisk-commits mailing list