diff options
author | Charles Forsyth <charles.forsyth@gmail.com> | 2018-12-23 13:10:38 +0000 |
---|---|---|
committer | Charles Forsyth <charles.forsyth@gmail.com> | 2018-12-23 13:10:38 +0000 |
commit | c3ac38156d7668879ad9f657c762febf341d49f5 (patch) | |
tree | c6c68762f8752a1386e239851901b1104dd85c3a | |
parent | f092bcd9be21a77f026a7c3227a920437d35b9e5 (diff) |
add -pprefix -t [trace] options to m4
-rw-r--r-- | appl/cmd/m4.b | 75 | ||||
-rw-r--r-- | dis/m4.dis | bin | 12287 -> 12809 bytes | |||
-rw-r--r-- | man/1/m4 | 19 |
3 files changed, 73 insertions, 21 deletions
diff --git a/appl/cmd/m4.b b/appl/cmd/m4.b index bc992b4f..a4648d4c 100644 --- a/appl/cmd/m4.b +++ b/appl/cmd/m4.b @@ -52,8 +52,11 @@ lquote := '`'; rquote := '\''; initcom := "#"; endcom := "\n"; +prefix := ""; bout: ref Iobuf; sh: Sh; +stderr: ref Sys->FD; +tracing := 0; init(nil: ref Draw->Context, args: list of string) { @@ -61,9 +64,27 @@ init(nil: ref Draw->Context, args: list of string) bufio = load Bufio Bufio->PATH; bout = bufio->fopen(sys->fildes(1), Sys->OWRITE); + stderr = sys->fildes(2); define("inferno", "inferno", 0); + arg := load Arg Arg->PATH; + arg->setusage("m4 [-t] [-pprefix] [-Dname[=value]] [-Qname[=value]] [-Uname] [file ...]"); + arg->init(args); + + while((o := arg->opt()) != 0){ + case o { + 'D' or 'Q' or 'U' => + ; # for second pass + 'p' => + prefix = arg->earg(); + 't' => + tracing = 1; + * => + arg->usage(); + } + } + builtin("changecom", dochangecom); builtin("changequote", dochangequote); builtin("copydef", docopydef); @@ -88,11 +109,9 @@ init(nil: ref Draw->Context, args: list of string) builtin("undefine", doundefine); builtin("undivert", doundivert); - arg := load Arg Arg->PATH; - arg->setusage("m4 [-Dname[=value]] [-Qname[=value]] [-Uname] [file ...]"); arg->init(args); - while((o := arg->opt()) != 0){ + while((o = arg->opt()) != 0){ case o { 'D' => argdefine(arg->earg(), 0); @@ -100,6 +119,10 @@ init(nil: ref Draw->Context, args: list of string) argdefine(arg->earg(), 1); 'U' => undefine(arg->earg()); + 'p' => + arg->earg(); + 't' => + ; * => arg->usage(); } @@ -157,7 +180,8 @@ error(s: string) ios := hd instack; where = sys->sprint(" %s:%d:", ios.name, ios.line); } - sys->fprint(sys->fildes(2), "m4:%s %s\n", where, s); + bout.flush(); + sys->fprint(stderr, "m4:%s %s\n", where, s); raise "fail:error"; } @@ -191,9 +215,12 @@ called(c: int) curarg = ref Param(""); nesting := 0; # () depth skipws(); + mark := instack; for(;;){ - if((c = getc()) < 0) + if((c = getc()) < 0) { + instack = mark; error("EOF in parameters"); + } if(isalpha(c)) called(c); else if(c == lquote) @@ -228,9 +255,12 @@ called(c: int) quoted() { nesting :=0; + mark := instack; while((c := getc()) != rquote || nesting > 0){ - if(c < 0) + if(c < 0) { + instack = mark; error("EOF in string"); + } if(c == rquote) nesting--; else if(c == lquote) @@ -276,19 +306,9 @@ isspace(c: int): int return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } -isname(s: string): int -{ - if(s == nil || !isalpha(s[0])) - return 0; - for(i := 1; i < len s; i++) - if(!(isalpha(s[i]) || s[i]>='0' && s[i]<='9')) - return 0; - return 1; -} - isalpha(c: int): int { - return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_' || c > 16rA0; + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_' || c > 16rA0 && c != lquote && c != rquote; } hash(name: string): int @@ -301,6 +321,13 @@ hash(name: string): int builtin(name: string, impl: ref fn(nil: array of string)) { + if(prefix != "") + name = prefix+name; + ibuiltin(name, impl); +} + +ibuiltin(name: string, impl: ref fn(nil: array of string)) +{ h := hash(name); n := ref Name(name, nil, impl, 0, 0); names[h] = n :: names[h]; @@ -418,6 +445,12 @@ putc(c: int) expand(def: ref Name, args: array of string) { + if(tracing){ + sys->fprint(stderr, "expand %s [%s]", args[0], def.name); + for(i := 1; i < len args; i++) + sys->fprint(stderr, " %d: [%s]", i, args[i]); + sys->fprint(stderr, "\n"); + } if(def.impl != nil){ def.impl(args); return; @@ -474,7 +507,7 @@ docopydef(args: array of string) if(n.impl == nil) define(args[2], n.repl, n.asis); else - builtin(args[2], n.impl); + ibuiltin(args[2], n.impl); }else define(args[2], "", 0); } @@ -524,12 +557,12 @@ doundivert(args: array of string) doifdef(args: array of string) { - if(len args < 2) + if(len args < 3) return; n := lookup(args[1]); if(n != nil) pushs(args[2]); - else if(len args > 2) + else if(len args > 3) pushs(args[3]); } @@ -642,7 +675,7 @@ doerrprint(args: array of string) for(i := 1; i < len args; i++) s += " "+args[i]; if(s != nil) - sys->fprint(sys->fildes(2), "m4:%s\n", s); + sys->fprint(stderr, "m4:%s\n", s); } dolen(args: array of string) Binary files differ@@ -4,6 +4,12 @@ m4 \- macro processor .SH SYNOPSIS .B m4 [ +.BI -p prefix +] +[ +.B -t +] +[ .BI -D name = value ] [ .BI -Q name = value @@ -236,7 +242,20 @@ Text may be undiverted into another diversion. Undiverting discards the diverted text. .PD .PP +The +.B -p +option causes +.I m4 +to add the given prefix character to the names of predefined macros; +typically the +.I prefix +is a Unicode character, to reduce the chance of a clash with macro names in the input text. +The +.B -t +option produces a trace on standard error. +.PP .I M4 +otherwise interprets its command line options after installing the predefined macro set. The .B -D |