This adds support for -s to the m4(1) utility, which causes #line directives
to be emitted as per the C preprocessor. It updates the manual page in regards to standards accordingly. PR: standards/36075 Submitted by: tjr Reviewed by: mike MFC after: 1 week
This commit is contained in:
parent
217b7e94cc
commit
116615d3b6
@ -584,7 +584,11 @@ char *ifile;
|
||||
errx(1, "too many include files");
|
||||
if ((infile[ilevel + 1] = fopen(ifile, "r")) != NULL) {
|
||||
ilevel++;
|
||||
if ((inname[ilevel] = strdup(ifile)) == NULL)
|
||||
err(1, NULL);
|
||||
inlineno[ilevel] = 1;
|
||||
bbase[ilevel] = bufbase = bp;
|
||||
emitline();
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
@ -604,9 +608,11 @@ char *pfile;
|
||||
register int c;
|
||||
|
||||
if ((pf = fopen(pfile, "r")) != NULL) {
|
||||
fprintf(active, "#line 1 \"%s\"\n", pfile);
|
||||
while ((c = getc(pf)) != EOF)
|
||||
putc(c, active);
|
||||
(void) fclose(pf);
|
||||
emitline();
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
|
@ -53,6 +53,7 @@ int dopaste(char *);
|
||||
void dopushdef(char *, char *);
|
||||
void dosub(char *[], int);
|
||||
void doundiv(char *[], int);
|
||||
void emitline(void);
|
||||
void eval(char *[], int, int);
|
||||
void expand(char *[], int);
|
||||
void getdiv(int);
|
||||
@ -72,6 +73,8 @@ extern ndptr hashtab[]; /* hash table for macros etc. */
|
||||
extern stae mstack[]; /* stack of m4 machine */
|
||||
extern FILE *active; /* active output file pointer */
|
||||
extern FILE *infile[]; /* input file stack (0=stdin) */
|
||||
extern char *inname[]; /* names of these input files */
|
||||
extern int inlineno[]; /* current number in each input*/
|
||||
extern FILE *outfile[]; /* diversion array(0=bitbucket) */
|
||||
extern int fp; /* m4 call frame pointer */
|
||||
extern int ilevel; /* input file stack pointer */
|
||||
@ -92,3 +95,5 @@ extern char *m4wraps; /* m4wrap string default. */
|
||||
extern char *null; /* as it says.. just a null. */
|
||||
extern char rquote; /* right quote character (') */
|
||||
extern char scommt; /* start character for comment */
|
||||
extern int synccpp; /* Line synchronisation for C preprocessor */
|
||||
extern int chscratch; /* Scratch space for gpbc() macro */
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\"
|
||||
.\" @(#) $FreeBSD$
|
||||
.\"
|
||||
.Dd January 26, 1993
|
||||
.Dd April 17, 2002
|
||||
.Dt M4 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -10,9 +10,9 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Oo
|
||||
.Fl D Ns Ar name Ns Op Ar =value
|
||||
.Fl D Ar name Ns Op Ar =value
|
||||
.Oc
|
||||
.Op Fl U Ns Ar name
|
||||
.Op Fl U Ar name
|
||||
.Op Ar filename
|
||||
\|.\|.\|.
|
||||
.Sh DESCRIPTION
|
||||
@ -41,13 +41,18 @@ the quote characters with the changequote built-in macro.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width "-Dname[=value]xxx"
|
||||
.It Fl D Ns Ar name Ns Oo
|
||||
.It Fl s
|
||||
Emit
|
||||
.Em #line
|
||||
directives for
|
||||
.Xr cpp 1 .
|
||||
.It Fl D Ar name Ns Oo
|
||||
.Ar =value
|
||||
.Oc
|
||||
Define the symbol
|
||||
.Ar name
|
||||
to have some value (or NULL).
|
||||
.It Fl "U" Ns Ar "name"
|
||||
.It Fl "U" Ar "name"
|
||||
Undefine the symbol
|
||||
.Ar name .
|
||||
.El
|
||||
@ -177,7 +182,35 @@ Flushes the named output queues (or all queues if no arguments).
|
||||
.It unix
|
||||
A pre-defined macro for testing the OS platform.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Ex -std
|
||||
.Pp
|
||||
The exit status can be specified by the input file using the
|
||||
.Em m4exit
|
||||
macro.
|
||||
.Sh "SEE ALSO"
|
||||
.Xr cpp 1
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is compatible with the
|
||||
.St -p1003.1-2001
|
||||
specification with the exception of the
|
||||
.Em traceon
|
||||
and
|
||||
.Em traceoff
|
||||
built-in macros, which are not implemented.
|
||||
.Pp
|
||||
The
|
||||
.Em expr ,
|
||||
.Em paste ,
|
||||
.Em spaste
|
||||
and
|
||||
.Em unix
|
||||
built-in macros are extensions to the standard.
|
||||
.Sh AUTHORS
|
||||
.An Ozan Yigit Aq oz@sis.yorku.ca
|
||||
and
|
||||
.An Richard A. O'Keefe Aq ok@goanna.cs.rmit.OZ.AU
|
||||
.Sh BUGS
|
||||
The tracing macros are not implemented.
|
||||
|
@ -80,6 +80,8 @@ char *endest= strspace+STRSPMAX;/* end of string space */
|
||||
int sp; /* current m4 stack pointer */
|
||||
int fp; /* m4 call frame pointer */
|
||||
FILE *infile[MAXINP]; /* input file stack (0=stdin) */
|
||||
char *inname[MAXINP]; /* names of these input files */
|
||||
int inlineno[MAXINP]; /* current number in each input*/
|
||||
FILE *outfile[MAXOUT]; /* diversion array(0=bitbucket)*/
|
||||
FILE *active; /* active output file pointer */
|
||||
char *m4temp; /* filename for diversions */
|
||||
@ -92,6 +94,8 @@ char lquote = LQUOTE; /* left quote character (`) */
|
||||
char rquote = RQUOTE; /* right quote character (') */
|
||||
char scommt = SCOMMT; /* start character for comment */
|
||||
char ecommt = ECOMMT; /* end character for comment */
|
||||
int synccpp; /* Line synchronisation for C preprocessor */
|
||||
int chscratch; /* Scratch space for gpbc() macro */
|
||||
|
||||
struct keyblk keywrds[] = { /* m4 keywords to be installed */
|
||||
"include", INCLTYPE,
|
||||
@ -159,7 +163,7 @@ main(argc,argv)
|
||||
|
||||
initkwds();
|
||||
|
||||
while ((c = getopt(argc, argv, "tD:U:o:")) != -1)
|
||||
while ((c = getopt(argc, argv, "D:U:s")) != -1)
|
||||
switch(c) {
|
||||
|
||||
case 'D': /* define something..*/
|
||||
@ -173,7 +177,9 @@ main(argc,argv)
|
||||
case 'U': /* undefine... */
|
||||
remhash(optarg, TOP);
|
||||
break;
|
||||
case 'o': /* specific output */
|
||||
case 's':
|
||||
synccpp = 1;
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
@ -195,6 +201,10 @@ main(argc,argv)
|
||||
sp = -1; /* stack pointer initialized */
|
||||
fp = 0; /* frame pointer initialized */
|
||||
infile[0] = stdin; /* default input (naturally) */
|
||||
if ((inname[0] = strdup("-")) == NULL)
|
||||
err(1, NULL);
|
||||
inlineno[0] = 1;
|
||||
emitline();
|
||||
macro();
|
||||
} else
|
||||
for (; argc--; ++argv) {
|
||||
@ -206,6 +216,10 @@ main(argc,argv)
|
||||
sp = -1;
|
||||
fp = 0;
|
||||
infile[0] = ifp;
|
||||
if ((inname[0] = strdup(p)) == NULL)
|
||||
err(1, NULL);
|
||||
inlineno[0] = 1;
|
||||
emitline();
|
||||
macro();
|
||||
if (ifp != stdin)
|
||||
(void)fclose(ifp);
|
||||
@ -282,7 +296,9 @@ macro() {
|
||||
break; /* all done thanks.. */
|
||||
--ilevel;
|
||||
(void) fclose(infile[ilevel+1]);
|
||||
free(inname[ilevel+1]);
|
||||
bufbase = bbase[ilevel];
|
||||
emitline();
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -419,3 +435,12 @@ initkwds() {
|
||||
p->type = keywrds[i].ktyp | STATIC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit preprocessor #line directive if -s option used. */
|
||||
void
|
||||
emitline(void)
|
||||
{
|
||||
if (synccpp)
|
||||
fprintf(active, "#line %d \"%s\"\n", inlineno[ilevel],
|
||||
inname[ilevel]);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mdef.h 8.1 (Berkeley) 6/6/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define MACRTYPE 1
|
||||
@ -142,7 +143,9 @@ typedef union { /* stack structure */
|
||||
* pushf() - push a call frame entry onto stack
|
||||
* pushs() - push a string pointer onto stack
|
||||
*/
|
||||
#define gpbc() (bp > bufbase) ? (*--bp ? *bp : EOF) : getc(infile[ilevel])
|
||||
#define gpbc() (bp > bufbase) ? (*--bp ? *bp : EOF) : \
|
||||
((chscratch = getc(infile[ilevel])) == '\n' && ++inlineno[ilevel], \
|
||||
chscratch)
|
||||
#define pushf(x) if (sp < STACKMAX) mstack[++sp].sfra = (x)
|
||||
#define pushs(x) if (sp < STACKMAX) mstack[++sp].sstr = (x)
|
||||
|
||||
|
@ -219,6 +219,7 @@ int n;
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: m4 [-Dname[=val]] [-Uname]\n");
|
||||
fprintf(stderr,
|
||||
"usage: m4 [-s] [-D name[=val]]... [-U name]... file...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user