Exemplo n.º 1
0
static void
do_regexpindex(const char *string, regex_t *re, regmatch_t *pm)
{
	int error;

	switch(error = regexec(re, string, re->re_nsub+1, pm, 0)) {
	case 0:
		pbunsigned(pm[0].rm_so);
		break;
	case REG_NOMATCH:
		pbnum(-1);
		break;
	default:
		exit_regerror(error, re);
	}
}
Exemplo n.º 2
0
/*
 * expand_macro - user-defined macro expansion
 */
void
expand_macro(const char *argv[], int argc)
{
	const char *t;
	const char *p;
	int n;
	int argno;

	t = argv[0];		       /* defn string as a whole */
	p = t;
	while (*p)
		p++;
	p--;			       /* last character of defn */
	while (p > t) {
		if (*(p - 1) != ARGFLAG)
			PUSHBACK(*p);
		else {
			switch (*p) {

			case '#':
				pbnum(argc - 2);
				break;
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				if ((argno = *p - '0') < argc - 1)
					pbstr(argv[argno + 1]);
				break;
			case '*':
				if (argc > 2) {
					for (n = argc - 1; n > 2; n--) {
						pbstr(argv[n]);
						pushback(COMMA);
					}
					pbstr(argv[2]);
				}
				break;
                        case '@':
				if (argc > 2) {
					for (n = argc - 1; n > 2; n--) {
						pbstr(rquote);
						pbstr(argv[n]);
						pbstr(lquote);
						pushback(COMMA);
					}
					pbstr(rquote);
					pbstr(argv[2]);
					pbstr(lquote);
				}
                                break;
			default:
				PUSHBACK(*p);
				PUSHBACK('$');
				break;
			}
			p--;
		}
		p--;
	}
	if (p == t)		       /* do last character */
		PUSHBACK(*p);
}
Exemplo n.º 3
0
/*
 * expand_builtin - evaluate built-in macros.
 */
void
expand_builtin(const char *argv[], int argc, int td)
{
	int c, n;
	int ac;
	static int sysval = 0;

#ifdef DEBUG
	printf("argc = %d\n", argc);
	for (n = 0; n < argc; n++)
		printf("argv[%d] = %s\n", n, argv[n]);
	fflush(stdout);
#endif

 /*
  * if argc == 3 and argv[2] is null, then we
  * have macro-or-builtin() type call. We adjust
  * argc to avoid further checking..
  */
 /* we keep the initial value for those built-ins that differentiate
  * between builtin() and builtin.
  */
	ac = argc;

	if (argc == 3 && !*(argv[2]) && !mimic_gnu)
		argc--;

	switch (td & TYPEMASK) {

	case DEFITYPE:
		if (argc > 2)
			dodefine(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case PUSDTYPE:
		if (argc > 2)
			dopushdef(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case DUMPTYPE:
		dodump(argv, argc);
		break;

	case TRACEONTYPE:
		dotrace(argv, argc, 1);
		break;

	case TRACEOFFTYPE:
		dotrace(argv, argc, 0);
		break;

	case EXPRTYPE:
	/*
	 * doexpr - evaluate arithmetic
	 * expression
	 */
	{
		int base = 10;
		int maxdigits = 0;
		const char *errstr;

		if (argc > 3) {
			base = strtonum(argv[3], 2, 36, &errstr);
			if (errstr) {
				m4errx(1, "expr: base %s invalid.", argv[3]);
			}
		}
		if (argc > 4) {
			maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
			if (errstr) {
				m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
			}
		}
		if (argc > 2)
			pbnumbase(expr(argv[2]), base, maxdigits);
		break;
	}

	case IFELTYPE:
		if (argc > 4)
			doifelse(argv, argc);
		break;

	case IFDFTYPE:
	/*
	 * doifdef - select one of two
	 * alternatives based on the existence of
	 * another definition
	 */
		if (argc > 3) {
			if (lookup_macro_definition(argv[2]) != NULL)
				pbstr(argv[3]);
			else if (argc > 4)
				pbstr(argv[4]);
		}
		break;

	case LENGTYPE:
	/*
	 * dolen - find the length of the
	 * argument
	 */
		pbnum((argc > 2) ? strlen(argv[2]) : 0);
		break;

	case INCRTYPE:
	/*
	 * doincr - increment the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) + 1);
		break;

	case DECRTYPE:
	/*
	 * dodecr - decrement the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) - 1);
		break;

	case SYSCTYPE:
	/*
	 * dosys - execute system command
	 */
		if (argc > 2) {
			fflush(stdout);
			sysval = system(argv[2]);
		}
		break;

	case SYSVTYPE:
	/*
	 * dosysval - return value of the last
	 * system call.
	 *
	 */
		pbnum(sysval);
		break;

	case ESYSCMDTYPE:
		if (argc > 2)
			doesyscmd(argv[2]);
		break;
	case INCLTYPE:
		if (argc > 2)
			if (!doincl(argv[2])) {
				if (mimic_gnu) {
					warn("%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
					exit_code = 1;
				} else
					err(1, "%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
			}
		break;

	case SINCTYPE:
		if (argc > 2)
			(void) doincl(argv[2]);
		break;
#ifdef EXTENDED
	case PASTTYPE:
		if (argc > 2)
			if (!dopaste(argv[2]))
				err(1, "%s at line %lu: paste(%s)", 
				    CURRENT_NAME, CURRENT_LINE, argv[2]);
		break;

	case SPASTYPE:
		if (argc > 2)
			(void) dopaste(argv[2]);
		break;
	case FORMATTYPE:
		doformat(argv, argc);
		break;
#endif
	case CHNQTYPE:
		dochq(argv, ac);
		break;

	case CHNCTYPE:
		dochc(argv, argc);
		break;

	case SUBSTYPE:
	/*
	 * dosub - select substring
	 *
	 */
		if (argc > 3)
			dosub(argv, argc);
		break;

	case SHIFTYPE:
	/*
	 * doshift - push back all arguments
	 * except the first one (i.e. skip
	 * argv[2])
	 */
		if (argc > 3) {
			for (n = argc - 1; n > 3; n--) {
				pbstr(rquote);
				pbstr(argv[n]);
				pbstr(lquote);
				pushback(COMMA);
			}
			pbstr(rquote);
			pbstr(argv[3]);
			pbstr(lquote);
		}
		break;

	case DIVRTYPE:
		if (argc > 2 && (n = atoi(argv[2])) != 0)
			dodiv(n);
		else {
			active = stdout;
			oindex = 0;
		}
		break;

	case UNDVTYPE:
		doundiv(argv, argc);
		break;

	case DIVNTYPE:
	/*
	 * dodivnum - return the number of
	 * current output diversion
	 */
		pbnum(oindex);
		break;

	case UNDFTYPE:
	/*
	 * doundefine - undefine a previously
	 * defined macro(s) or m4 keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_undefine(argv[n]);
		break;

	case POPDTYPE:
	/*
	 * dopopdef - remove the topmost
	 * definitions of macro(s) or m4
	 * keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_popdef(argv[n]);
		break;

	case MKTMTYPE:
	/*
	 * dotemp - create a temporary file
	 */
		if (argc > 2) {
			int fd;
			char *temp;

			temp = xstrdup(argv[2]);

			fd = mkstemp(temp);
			if (fd == -1)
				err(1,
	    "%s at line %lu: couldn't make temp file %s",
	    CURRENT_NAME, CURRENT_LINE, argv[2]);
			close(fd);
			pbstr(temp);
			free(temp);
		}
		break;

	case TRNLTYPE:
	/*
	 * dotranslit - replace all characters in
	 * the source string that appears in the
	 * "from" string with the corresponding
	 * characters in the "to" string.
	 */
		if (argc > 3) {
			char *temp;

			temp = xalloc(strlen(argv[2])+1, NULL);
			if (argc > 4)
				map(temp, argv[2], argv[3], argv[4]);
			else
				map(temp, argv[2], argv[3], null);
			pbstr(temp);
			free(temp);
		} else if (argc > 2)
			pbstr(argv[2]);
		break;

	case INDXTYPE:
	/*
	 * doindex - find the index of the second
	 * argument string in the first argument
	 * string. -1 if not present.
	 */
		pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
		break;

	case ERRPTYPE:
	/*
	 * doerrp - print the arguments to stderr
	 * file
	 */
		if (argc > 2) {
			for (n = 2; n < argc; n++)
				fprintf(stderr, "%s ", argv[n]);
			fprintf(stderr, "\n");
		}
		break;

	case DNLNTYPE:
	/*
	 * dodnl - eat-up-to and including
	 * newline
	 */
		while ((c = gpbc()) != '\n' && c != EOF)
			;
		break;

	case M4WRTYPE:
	/*
	 * dom4wrap - set up for
	 * wrap-up/wind-down activity
	 */
		if (argc > 2)
			dom4wrap(argv[2]);
		break;

	case EXITTYPE:
	/*
	 * doexit - immediate exit from m4.
	 */
		killdiv();
		exit((argc > 2) ? atoi(argv[2]) : 0);
		break;

	case DEFNTYPE:
		if (argc > 2)
			for (n = 2; n < argc; n++)
				dodefn(argv[n]);
		break;

	case INDIRTYPE:	/* Indirect call */
		if (argc > 2)
			doindir(argv, argc);
		break;

	case BUILTINTYPE: /* Builtins only */
		if (argc > 2)
			dobuiltin(argv, argc);
		break;

	case PATSTYPE:
		if (argc > 2)
			dopatsubst(argv, argc);
		break;
	case REGEXPTYPE:
		if (argc > 2)
			doregexp(argv, argc);
		break;
	case LINETYPE:
		doprintlineno(infile+ilevel);
		break;
	case FILENAMETYPE:
		doprintfilename(infile+ilevel);
		break;
	case SELFTYPE:
		pbstr(rquote);
		pbstr(argv[1]);
		pbstr(lquote);
		break;
	default:
		m4errx(1, "eval: major botch.");
		break;
	}
}
Exemplo n.º 4
0
PRIVATE void evalvar()
{
	if( symb == s_var ) pbnum(tokval);
	else pbhex(tokval);
}
Exemplo n.º 5
0
static void
expand(wchar_t **a1, int c)
{
	wchar_t	*dp;
	struct nlist	*sp;

	sp = (struct nlist *)a1[-1];

	if (sp->tflag || trace) {
#if !defined(__lint)	/* lint doesn't grok "%ws" */
		int	i;

		(void) fprintf(stderr,
		    "Trace(%d): %ws", Cp-callst, a1[0]);
#endif

		if (c > 0) {
#if !defined(__lint)	/* lint doesn't grok "%ws" */
			(void) fprintf(stderr, "(%ws", chkbltin(a1[1]));
			for (i = 2; i <= c; ++i)
				(void) fprintf(stderr, ",%ws", chkbltin(a1[i]));
#endif
			(void) fprintf(stderr, ")");
		}
		(void) fprintf(stderr, "\n");
	}

	dp = sp->def;

	for (; *dp; ++dp) {
		if (is_builtin(*dp)) {
			(*barray[builtin_idx(*dp)].bfunc)(a1, c);
		} else if (dp[1] == '$') {
			if (is_digit(*dp)) {
				int	n;
				if ((n = *dp-'0') <= c)
					pbstr(a1[n]);
				++dp;
			} else if (*dp == '#') {
				pbnum((long)c);
				++dp;
			} else if (*dp == '*' || *dp == '@') {
				int i = c;
				wchar_t **a = a1;

				if (i > 0)
					for (;;) {
						if (*dp == '@')
							pbstr(rquote);

						pbstr(a[i--]);

						if (*dp == '@')
							pbstr(lquote);

						if (i <= 0)
						break;

						pbstr(L",");
					}
				++dp;
			} else
				putbak(*dp);
		} else
			putbak(*dp);
	}
}