summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Millaway <john43@users.sourceforge.net>2003-03-18 20:17:50 +0000
committerJohn Millaway <john43@users.sourceforge.net>2003-03-18 20:17:50 +0000
commitafaf3daca09119d5d1a6391ba84bef288e77fdfd (patch)
tree3766866173136ba5d4f013593bf4a9205b6ce5aa
parent0fd9a683598f6f295d11b34412c6c7df10dec7dc (diff)
Fixed #line directives.
-rw-r--r--filter.c123
-rw-r--r--flexdef.h14
-rw-r--r--main.c3
-rw-r--r--regex.c46
4 files changed, 131 insertions, 55 deletions
diff --git a/filter.c b/filter.c
index 71c7779..f0c27da 100644
--- a/filter.c
+++ b/filter.c
@@ -135,17 +135,17 @@ bool filter_apply_chain (struct filter * chain)
{
int pid, pipes[2];
- /* Tricky recursion, since we want to begin the chain
- * at the END. Why? Because we need all the forked processes
- * to be children of the main flex process.
- */
+ /* Tricky recursion, since we want to begin the chain
+ * at the END. Why? Because we need all the forked processes
+ * to be children of the main flex process.
+ */
if (chain)
- filter_apply_chain(chain->next);
- else
- return true;
+ filter_apply_chain (chain->next);
+ else
+ return true;
- /* Now we are the right-most unprocessed link in the chain.
- */
+ /* Now we are the right-most unprocessed link in the chain.
+ */
fflush (stdout);
fflush (stderr);
@@ -165,22 +165,22 @@ bool filter_apply_chain (struct filter * chain)
/* run as a filter, either internally or by exec */
if (chain->filter_func) {
- int r;
+ int r;
- /* setup streams again */
- if ((stdin = fdopen (0, "r")) == NULL)
- flexfatal (_("fdopen(0) failed"));
- if ((stdout = fdopen (1, "w")) == NULL)
- flexfatal (_("fdopen(1) failed"));
+ /* setup streams again */
+ if ((stdin = fdopen (0, "r")) == NULL)
+ flexfatal (_("fdopen(0) failed"));
+ if ((stdout = fdopen (1, "w")) == NULL)
+ flexfatal (_("fdopen(1) failed"));
- if((r = chain->filter_func (chain)) == -1)
+ if ((r = chain->filter_func (chain)) == -1)
flexfatal (_("filter_func failed"));
- exit(0);
+ exit (0);
}
else {
- execvp (chain->argv[0],
- (char **const) (chain->argv));
- flexfatal (_("exec failed"));
+ execvp (chain->argv[0],
+ (char **const) (chain->argv));
+ flexfatal (_("exec failed"));
}
exit (1);
@@ -234,13 +234,15 @@ int filter_tee_header (struct filter *chain)
int to_cfd;
FILE *to_c, *to_h;
- fprintf(stderr,"filter_tee()\n");fflush(stderr);
+ fprintf (stderr, "filter_tee()\n");
+ fflush (stderr);
if (!chain->extra) {
/* No header file was specified, so we become a transparent
* filter.
*/
- fprintf(stderr,"\texeclp(cat)\n");fflush(stderr);
+ fprintf (stderr, "\texeclp(cat)\n");
+ fflush (stderr);
execlp ("cat", "cat", NULL);
flexfatal (_("exec failed"));
}
@@ -264,8 +266,9 @@ int filter_tee_header (struct filter *chain)
/* Now to_c is a pipe to the C branch, and to_h is a pipe to the H branch.
*/
- fprintf(stderr,"\tpid(%d): to_c=%d, to_h=%d\n",
- getpid(),fileno(to_c),fileno(to_h)); fflush(stderr);
+ fprintf (stderr, "\tpid(%d): to_c=%d, to_h=%d\n",
+ getpid (), fileno (to_c), fileno (to_h));
+ fflush (stderr);
fputs ("m4_changequote`'m4_dnl\n", to_h);
fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_h);
@@ -289,46 +292,64 @@ int filter_tee_header (struct filter *chain)
fclose (to_c);
fflush (to_h);
- fclose (to_h);
+ fclose (to_h);
- while(wait(0) > 0)
- ;
+ while (wait (0) > 0) ;
- exit(0);
- return 0;
+ exit (0);
+ return 0;
}
-int filter_fix_linedirs(struct filter *chain)
+int filter_fix_linedirs (struct filter *chain)
{
- regex_t reg_ld;
char *buf;
const int readsz = 512;
- int err;
-
- if(!chain)
- return 0;
-
-/* We only care about matching line directives that flex generates. */
-#define REGEXP_LINEDIR "^#line ([[:digit:]]+) \"(.*\")"
-
- buf = (char*) flex_alloc(readsz);
- memset(&reg_ld,0,sizeof(regex_t));
+ int lineno=1;
+ bool in_gen = true;/* in generated code */
- if((err = regcomp(&reg_ld, REGEXP_LINEDIR, REG_EXTENDED)) != 0){
- regerror(err, &reg_ld, buf, readsz);
- sprintf( buf, "regcomp failed: %s\n", buf);
- flexfatal ( buf );
- }
+ if (!chain)
+ return 0;
- while(fgets(buf,readsz,stdin)){
- if( buf[0] == '#' && regexec(&reg_ld,buf, 0, NULL, 0) == 0){
+ buf = (char *) flex_alloc (readsz);
+ while (fgets (buf, readsz, stdin)) {
+ regmatch_t m[10];
+
+ if (buf[0] == '#'
+ && regexec (&regex_linedir, buf, 3, m, 0) == 0) {
+
+ int num;
+ char * fname;
+
+ /* extract the line number and filename */
+ num = regmatch_strtol(&m[1], buf, NULL, 0);
+ fname = regmatch_dup(&m[2], buf);
+
+ if ( strcmp(fname, outfilename?outfilename:"") ==0
+ || strcmp(fname, headerfilename?headerfilename:"") ==0
+ ){
+ /* Adjust the line directives. */
+ in_gen = true;
+ fprintf(stdout, "#line %d \"%s\"\n", lineno+1, fname);
+ free(fname);
+
+ }
+ else{
+ /* it's a #line directive for code we didn't write */
+ in_gen= false;
+ fputs (buf, stdout);
+ }
+ }
+ else{
+ /* It's just a regular line of code. */
+ fputs(buf, stdout);
}
- fputs(buf, stdout);
- }
+ lineno++;
+ }
+ fflush(stdout);
- return 0;
+ return 0;
}
/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */
diff --git a/flexdef.h b/flexdef.h
index 1b7ce9b..874a0e8 100644
--- a/flexdef.h
+++ b/flexdef.h
@@ -1167,4 +1167,18 @@ extern int filter_truncate (struct filter * chain, int max_len);
extern int filter_tee_header PROTO((struct filter *chain));
extern int filter_fix_linedirs PROTO((struct filter *chain));
+
+/*
+ * From "regex.c"
+ */
+
+extern regex_t regex_linedir;
+bool flex_init_regex(void);
+void flex_regcomp(regex_t *preg, const char *regex, int cflags);
+char *regmatch_dup (regmatch_t * m, const char *src);
+char *regmatch_cpy (regmatch_t * m, char *dest, const char *src);
+int regmatch_len (regmatch_t * m);
+int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, int base);
+bool regmatch_empty (regmatch_t * m);
+
#endif /* not defined FLEXDEF_H */
diff --git a/main.c b/main.c
index f8d1777..5e32e7d 100644
--- a/main.c
+++ b/main.c
@@ -343,6 +343,7 @@ void check_options ()
/* Setup the filter chain. */
output_chain = filter_create_int(NULL, filter_tee_header, headerfilename);
filter_create_ext(output_chain,"m4","-P",0);
+ filter_create_int(output_chain, filter_fix_linedirs, NULL);
/* For debugging, only run the requested number of filters. */
if (preproc_level > 0) {
@@ -1107,6 +1108,8 @@ void flexinit (argc, argv)
buf_append (&m4defs_buf, &m4defs_init_str, 2);
}
+ /* initialize regex lib */
+ flex_init_regex();
/* Enable C++ if program name ends with '+'. */
program_name = basename2 (argv[0], 0);
diff --git a/regex.c b/regex.c
index c430825..2460dab 100644
--- a/regex.c
+++ b/regex.c
@@ -33,6 +33,46 @@
#include "flexdef.h"
+
+static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
+
+regex_t regex_linedir; /*<< matches line directives */
+
+
+/** Initialize the regular expressions.
+ * @return true upon success.
+ */
+bool flex_init_regex(void)
+{
+ flex_regcomp(&regex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
+
+ return true;
+}
+
+/** Compiles a regular expression or dies trying.
+ * @param preg Same as for regcomp().
+ * @param regex Same as for regcomp().
+ * @param cflags Same as for regcomp().
+ */
+void flex_regcomp(regex_t *preg, const char *regex, int cflags)
+{
+ int err;
+
+ memset (preg, 0, sizeof (regex_t));
+
+ if ((err = regcomp (preg, regex, cflags)) != 0) {
+ const int errbuf_sz = 200;
+ char * errbuf=0;
+
+ errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
+ regerror (err, preg, errbuf, errbuf_sz);
+ sprintf (errbuf, "regcomp failed: %s\n", errbuf);
+
+ flexfatal (errbuf);
+ free(errbuf);
+ }
+}
+
/** Extract a copy of the match, or NULL if no match.
* @param m A match as returned by regexec().
* @param src The source string that was passed to regexec().
@@ -60,16 +100,14 @@ char *regmatch_dup (regmatch_t * m, const char *src)
*/
char *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
{
- int len;
-
if (m == NULL || m->rm_so < 0) {
if (dest)
dest[0] = '\0';
return dest;
}
- len = m->rm_eo - m->rm_so;
- return strcpy (dest, src + m->rm_so + len);
+ snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
+ return dest;
}
/** Get the length in characters of the match.