summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--appl/cmd/m4.b50
-rw-r--r--dis/m4.disbin12295 -> 12287 bytes
-rw-r--r--man/1/m421
3 files changed, 44 insertions, 27 deletions
diff --git a/appl/cmd/m4.b b/appl/cmd/m4.b
index f24427b6..39558384 100644
--- a/appl/cmd/m4.b
+++ b/appl/cmd/m4.b
@@ -25,6 +25,7 @@ Name: adt {
repl: string;
impl: ref fn(nil: array of string);
dol: int; # repl contains $[0-9]
+ asis: int; # replacement text not rescanned
text: fn(n: self ref Name): string;
};
@@ -61,7 +62,7 @@ init(nil: ref Draw->Context, args: list of string)
bout = bufio->fopen(sys->fildes(1), Sys->OWRITE);
- define("inferno", "inferno");
+ define("inferno", "inferno", 0);
builtin("changecom", dochangecom);
builtin("changequote", dochangequote);
@@ -88,20 +89,15 @@ init(nil: ref Draw->Context, args: list of string)
builtin("undivert", doundivert);
arg := load Arg Arg->PATH;
- arg->setusage("m4 [-Dname[=value]] [-Uname] [file ...]");
+ arg->setusage("m4 [-Dname[=value]] [-Qname[=value]] [-Uname] [file ...]");
arg->init(args);
while((o := arg->opt()) != 0){
case o {
'D' =>
- s := arg->earg();
- for(i := 0; i < len s; i++)
- if(s[i] == '='){
- define(s[0: i], s[i+1:]);
- break;
- }
- if(i == len s)
- define(s[0: i], "");
+ argdefine(arg->earg(), 0);
+ 'Q' =>
+ argdefine(arg->earg(), 1);
'U' =>
undefine(arg->earg());
* =>
@@ -126,6 +122,20 @@ init(nil: ref Draw->Context, args: list of string)
bout.flush();
}
+argdefine(s: string, asis: int)
+{
+ text := "";
+ for(i := 0; i < len s; i++)
+ if(s[i] == '='){
+ text = s[i+1:];
+ break;
+ }
+ n := lookup(s[0: i]);
+ if(n != nil && n.impl != nil)
+ error(sys->sprint("can't redefine built-in %s", s[0: i]));
+ define(s[0: i], text, asis);
+}
+
scan()
{
while((c := getc()) >= 0){
@@ -169,7 +179,7 @@ called(c: int)
puts(tok);
return;
}
- if(c != '('){ # no parameters
+ if(c != '(' || def.asis){ # no parameters
pushc(c);
expand(def, array[] of {tok});
return;
@@ -292,24 +302,22 @@ hash(name: string): int
builtin(name: string, impl: ref fn(nil: array of string))
{
h := hash(name);
- n := ref Name(name, nil, impl, 0);
+ n := ref Name(name, nil, impl, 0, 0);
names[h] = n :: names[h];
}
-define(name: string, repl: string)
+define(name: string, repl: string, asis: int)
{
h := hash(name);
dol := hasdol(repl);
for(l := names[h]; l != nil; l = tl l){
n := hd l;
if(n.name == name){
- n.impl = nil;
- n.repl = repl;
- n.dol = dol;
+ *n = Name(name, repl, nil, dol, asis);
return;
}
}
- n := ref Name(name, repl, nil, dol);
+ n := ref Name(name, repl, nil, dol, asis);
names[h] = n :: names[h];
}
@@ -447,9 +455,9 @@ hasdol(s: string): int
dodefine(args: array of string)
{
if(len args > 2)
- define(args[1], args[2]);
+ define(args[1], args[2], 0);
else if(len args > 1)
- define(args[1], "");
+ define(args[1], "", 0);
}
doundefine(args: array of string)
@@ -464,11 +472,11 @@ docopydef(args: array of string)
undefine(args[2]);
if((n := lookup(args[1])) != nil){
if(n.impl == nil)
- define(args[2], n.repl);
+ define(args[2], n.repl, n.asis);
else
builtin(args[2], n.impl);
}else
- define(args[2], "");
+ define(args[2], "", 0);
}
}
diff --git a/dis/m4.dis b/dis/m4.dis
index 6911a452..b3163800 100644
--- a/dis/m4.dis
+++ b/dis/m4.dis
Binary files differ
diff --git a/man/1/m4 b/man/1/m4
index dfab4fb0..ef0670a3 100644
--- a/man/1/m4
+++ b/man/1/m4
@@ -6,6 +6,8 @@ m4 \- macro processor
[
.BI -D name = value
] [
+.BI -Q name = value
+] [
.BI -U name
] [
.I file
@@ -235,17 +237,24 @@ Undiverting discards the diverted text.
.PD
.PP
.I M4
-interprets the
-.B -D
-and
-.B -U
-command line options after installing the predefined macro set.
+interprets its command line options after installing the predefined macro set.
The
.B -D
option defines
.I name
as a macro with the given
-.IR value .
+.IR value ;
+.B -Q
+defines
+.I name
+as a macro with the given
+.IR value
+that is regarded as always quoted (ie, is never rescanned).
+Neither
+.B -D
+nor
+.B -Q
+may change a predefined macro.
The
.B -U
option