-/* $OpenBSD: eval.c,v 1.63 2006/03/24 08:03:44 espie Exp $ */
+/* $OpenBSD: eval.c,v 1.64 2008/08/16 12:21:46 espie Exp $ */
/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */
/*
*/
ac = argc;
- if (argc == 3 && !*(argv[2]))
+ if (argc == 3 && !*(argv[2]) && !mimic_gnu)
argc--;
switch (td & TYPEMASK) {
void
dodefine(const char *name, const char *defn)
{
- if (!*name)
+ if (!*name && !mimic_gnu)
m4errx(1, "null definition.");
- macro_define(name, defn);
+ else
+ macro_define(name, defn);
}
/*
static void
dopushdef(const char *name, const char *defn)
{
- if (!*name)
+ if (!*name && !mimic_gnu)
m4errx(1, "null definition.");
- macro_pushdef(name, defn);
+ else
+ macro_pushdef(name, defn);
}
/*
-/* $OpenBSD: extern.h,v 1.45 2006/03/20 20:27:45 espie Exp $ */
+/* $OpenBSD: extern.h,v 1.46 2008/08/16 12:21:46 espie Exp $ */
/* $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $ */
/*-
extern void resizedivs(int);
extern size_t buffer_mark(void);
extern void dump_buffer(FILE *, size_t);
-extern void m4errx(int, const char *, ...);
+extern void __dead m4errx(int, const char *, ...);
extern int obtain_char(struct input_file *);
extern void set_input(struct input_file *, FILE *, const char *);
/* and corresponding exposure for local symbols */
extern void enlarge_bufspace(void);
extern void enlarge_strspace(void);
-extern char *endpbb;
+extern unsigned char *endpbb;
extern char *endest;
/* trace.c */
extern int ilevel; /* input file stack pointer */
extern int oindex; /* diversion index. */
extern int sp; /* current m4 stack pointer */
-extern char *bp; /* first available character */
-extern char *buf; /* push-back buffer */
-extern char *bufbase; /* buffer base for this ilevel */
-extern char *bbase[]; /* buffer base per ilevel */
+extern unsigned char *bp; /* first available character */
+extern unsigned char *buf; /* push-back buffer */
+extern unsigned char *bufbase; /* buffer base for this ilevel */
+extern unsigned char *bbase[]; /* buffer base per ilevel */
extern char ecommt[MAXCCHARS+1];/* end character for comment */
extern char *ep; /* first free char in strspace */
extern char lquote[MAXCCHARS+1];/* left quote character (`) */
-/* $OpenBSD: gnum4.c,v 1.36 2006/03/24 08:03:44 espie Exp $ */
+/* $OpenBSD: gnum4.c,v 1.37 2008/08/16 12:21:46 espie Exp $ */
/*
* Copyright (c) 1999 Marc Espie
{
const char *format = argv[2];
int pos = 3;
+ int left_padded;
+ long width;
+ size_t l;
+ const char *thisarg;
+ char temp[2];
+ long extra;
while (*format != 0) {
if (*format != '%') {
addchar(*format++);
+ continue;
+ }
+
+ format++;
+ if (*format == '%') {
+ addchar(*format++);
+ continue;
+ }
+ if (*format == 0) {
+ addchar('%');
+ break;
+ }
+
+ if (*format == '*') {
+ format++;
+ if (pos >= argc)
+ m4errx(1,
+ "Format with too many format specifiers.");
+ width = strtol(argv[pos++], NULL, 10);
+ } else {
+ width = strtol(format, (char **)&format, 10);
+ }
+ if (width < 0) {
+ left_padded = 1;
+ width = -width;
} else {
+ left_padded = 0;
+ }
+ if (*format == '.') {
format++;
- if (*format == '%' || *format == 0) {
- addchar('%');
- if (*format == '%')
- format++;
+ if (*format == '*') {
+ format++;
+ if (pos >= argc)
+ m4errx(1,
+ "Format with too many format specifiers.");
+ extra = strtol(argv[pos++], NULL, 10);
} else {
- int left_padded = 0;
- unsigned long width;
- size_t l;
-
- if (*format == '-') {
- left_padded = 1;
- format++;
- }
- width = strtoul(format, (char **)&format, 10);
- if (*format != 's') {
- m4errx(1, "Unsupported format specification: %s.", argv[2]);
- }
- format++;
- if (pos >= argc)
- m4errx(1, "Format with too many values.");
- l = strlen(argv[pos]);
- if (!left_padded) {
- while (l < width--)
- addchar(' ');
- }
- addchars(argv[pos++], l);
- if (left_padded) {
- while (l < width--)
- addchar(' ');
- }
+ extra = strtol(format, (char **)&format, 10);
}
+ } else {
+ extra = LONG_MAX;
+ }
+ if (pos >= argc)
+ m4errx(1, "Format with too many format specifiers.");
+ switch(*format) {
+ case 's':
+ thisarg = argv[pos++];
+ break;
+ case 'c':
+ temp[0] = strtoul(argv[pos++], NULL, 10);
+ temp[1] = 0;
+ thisarg = temp;
+ break;
+ default:
+ m4errx(1, "Unsupported format specification: %s.",
+ argv[2]);
+ }
+ format++;
+ l = strlen(thisarg);
+ if (l > extra)
+ l = extra;
+ if (!left_padded) {
+ while (l < width--)
+ addchar(' ');
+ }
+ addchars(thisarg, l);
+ if (left_padded) {
+ while (l < width--)
+ addchar(' ');
}
}
pbstr(getstring());
-.\" @(#) $OpenBSD: m4.1,v 1.50 2007/05/31 19:20:12 jmc Exp $
+.\" @(#) $OpenBSD: m4.1,v 1.51 2008/08/16 12:21:46 espie Exp $
.\"
.\" Copyright (c) 1989, 1993
.\" The Regents of the University of California. All rights reserved.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: August 16 2008 $
.Dt M4 1
.Os
.Sh NAME
In this mode, translit handles simple character
ranges (e.g., a-z), regular expressions mimic emacs behavior,
multiple m4wrap calls are handled as a stack,
-and the number of diversions is unlimited.
+the number of diversions is unlimited,
+empty names for macro definitions are allowed,
+and eval understands
+.Sq 0rbase:value
+numbers.
.It Fl I Ar "dirname"
Add directory
.Ar dirname
.Fa arg1
and following arguments, in a way similar to
.Xr printf 3 .
-This built-in is only available in GNU-m4 compatibility mode, and the
-left-padding flag, an optional field width and the %s data type
-are the only supported parameters.
+This built-in is only available in GNU-m4 compatibility mode, and the only
+parameters implemented are there for autoconf compatibility:
+left-padding flag, an optional field width, a maximum field width, *-specified field widths, and the %s and %c data type.
.It Fn ifdef name yes no
If the macro named by the first argument is defined then return the second
argument, otherwise the third.
-/* $OpenBSD: main.c,v 1.75 2008/08/16 12:19:49 espie Exp $ */
+/* $OpenBSD: main.c,v 1.76 2008/08/16 12:21:46 espie Exp $ */
/* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */
/*-
case LPAREN:
if (PARLEV > 0)
chrsave(t);
- while (isspace(l = gpbc()))
- ; /* skip blank, tab, nl.. */
+ while (isspace(l = gpbc())) /* skip blank, tab, nl.. */
+ if (PARLEV > 0)
+ chrsave(l);
pushback(l);
record(paren, PARLEV++);
break;
-/* $OpenBSD: misc.c,v 1.37 2007/05/05 03:42:49 ray Exp $ */
+/* $OpenBSD: misc.c,v 1.38 2008/08/16 12:21:46 espie Exp $ */
/* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */
/*
static size_t strsize = STRSPMAX;
static size_t bufsize = BUFSIZE;
-char *buf; /* push-back buffer */
-char *bufbase; /* the base for current ilevel */
-char *bbase[MAXINP]; /* the base for each ilevel */
-char *bp; /* first available character */
-char *endpbb; /* end of push-back buffer */
+unsigned char *buf; /* push-back buffer */
+unsigned char *bufbase; /* the base for current ilevel */
+unsigned char *bbase[MAXINP]; /* the base for each ilevel */
+unsigned char *bp; /* first available character */
+unsigned char *endpbb; /* end of push-back buffer */
/*
strspace = xalloc(strsize+1, NULL);
ep = strspace;
endest = strspace+strsize;
- buf = (char *)xalloc(bufsize, NULL);
+ buf = (unsigned char *)xalloc(bufsize, NULL);
bufbase = buf;
bp = buf;
endpbb = buf + bufsize;
void
enlarge_bufspace()
{
- char *newbuf;
+ unsigned char *newbuf;
int i;
bufsize += bufsize/2;
void
dump_buffer(FILE *f, size_t m)
{
- char *s;
+ unsigned char *s;
for (s = bp; s-buf > m;)
fputc(*--s, f);
%{
-/* $OpenBSD: parser.y,v 1.3 2006/01/20 23:10:19 espie Exp $ */
+/* $OpenBSD: parser.y,v 1.4 2008/08/16 12:21:46 espie Exp $ */
/*
* Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org>
*
extern int yyerror(const char *);
%}
%token NUMBER
+%token ERROR
%left LOR
%left LAND
%left '|'
%{
-/* $OpenBSD: tokenizer.l,v 1.3 2006/01/20 23:10:19 espie Exp $ */
+/* $OpenBSD: tokenizer.l,v 1.4 2008/08/16 12:21:46 espie Exp $ */
/*
* Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org>
*
#include <stdint.h>
#include <limits.h>
+extern int mimic_gnu;
extern int32_t yylval;
int32_t number(void);
+int32_t parse_radix(void);
%}
delim [ \t\n]
hex 0[xX][0-9a-fA-F]+
oct 0[0-7]*
dec [1-9][0-9]*
+radix 0[rR][0-9]+:[0-9a-zA-Z]+
%%
{ws} {/* just skip it */}
{hex}|{oct}|{dec} { yylval = number(); return(NUMBER); }
+{radix} { if (mimic_gnu) {
+ yylval = parse_radix(); return(NUMBER);
+ } else {
+ return(ERROR);
+ }
+ }
"<=" { return(LE); }
">=" { return(GE); }
"<<" { return(LSHIFT); }
fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext);
}
return l;
+}
+
+int32_t
+parse_radix()
+{
+ long base;
+ char *next;
+ long l;
+ l = 0;
+ base = strtol(yytext+2, &next, 0);
+ if (base > 36 || next == NULL) {
+ fprintf(stderr, "m4: error in number %s\n", yytext);
+ } else {
+ next++;
+ while (*next != 0) {
+ if (*next >= '0' && *next <= '9')
+ l = base * l + *next - '0';
+ else if (*next >= 'a' && *next <= 'z')
+ l = base * l + *next - 'a' + 10;
+ else if (*next >= 'A' && *next <= 'Z')
+ l = base * l + *next - 'A' + 10;
+ next++;
+ }
+ }
+ return l;
}
+