Exemplo n.º 1
0
Arquivo: regex.c Projeto: 0mp/freebsd
/** Convert a regmatch_t object to an integer using the strtol() function.
 * @param m A match as returned by regexec().
 * @param src The source string that was passed to regexec().
 * @param endptr Same as the second argument to strtol().
 * @param base   Same as the third argument to strtol().
 * @return The converted integer or error (Return value is the same as for strtol()).
 */
int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
		     int base)
{
	int     n = 0;

#define bufsz 20
	char    buf[bufsz];
	char   *s;

	if (m == NULL || m->rm_so < 0)
		return 0;

	if (regmatch_len (m) < bufsz)
		s = regmatch_cpy (m, buf, src);
	else
		s = regmatch_dup (m, src);

	n = strtol (s, endptr, base);

	if (s != buf)
		free (s);

	return n;
}
Exemplo n.º 2
0
/** Adjust the line numbers in the #line directives of the generated scanner.
 * After the m4 expansion, the line numbers are incorrect since the m4 macros
 * can add or remove lines.  This only adjusts line numbers for generated code,
 * not user code. This also happens to be a good place to squeeze multiple
 * blank lines into a single blank line.
 */
int filter_fix_linedirs (struct filter *chain)
{
	char   *buf;
	const int readsz = 512;
	int     lineno = 1;
	bool    in_gen = true;	/* in generated code */
	bool    last_was_blank = false;

	if (!chain)
		return 0;

	buf = malloc(readsz);
	if (!buf)
		flexerror(_("malloc failed in filter_fix_linedirs"));

	while (fgets (buf, readsz, stdin)) {

		regmatch_t m[10];

		/* Check for #line directive. */
		if (buf[0] == '#'
			&& regexec (&regex_linedir, buf, 3, m, 0) == 0) {

			char   *fname;

			/* extract the line number and filename */
			fname = regmatch_dup (&m[2], buf);

			if (strcmp (fname,
				outfilename ? outfilename : "<stdout>")
					== 0
			 || strcmp (fname,
			 	headerfilename ? headerfilename : "<stdout>")
					== 0) {

				char    *s1, *s2;
				char	filename[MAXLINE];

				s1 = fname;
				s2 = filename;

				while ((s2 - filename) < (MAXLINE - 1) && *s1) {
					/* Escape the backslash */
					if (*s1 == '\\')
						*s2++ = '\\';
					/* Escape the double quote */
					if (*s1 == '\"')
						*s2++ = '\\';
					/* Copy the character as usual */
					*s2++ = *s1++;
				}

				*s2 = '\0';

				/* Adjust the line directives. */
				in_gen = true;
				snprintf (buf, readsz, "#line %d \"%s\"\n",
					  lineno + 1, filename);
			}
			else {
				/* it's a #line directive for code we didn't write */
				in_gen = false;
			}

			free (fname);
			last_was_blank = false;
		}

		/* squeeze blank lines from generated code */
		else if (in_gen
			 && regexec (&regex_blank_line, buf, 0, NULL,
				     0) == 0) {
			if (last_was_blank)
				continue;
			else
				last_was_blank = true;
		}

		else {
			/* it's a line of normal, non-empty code. */
			last_was_blank = false;
		}

		fputs (buf, stdout);
		lineno++;
	}
	fflush (stdout);
	if (ferror (stdout))
		lerr (_("error writing output file %s"),
			outfilename ? outfilename : "<stdout>");

	else if (fclose (stdout))
		lerr (_("error closing output file %s"),
			outfilename ? outfilename : "<stdout>");

	return 0;
}