⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pval.c

📁 asterisk 是一个很有知名度开源软件
💻 C
📖 第 1 页 / 共 5 页
字号:
				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 + -