-/* $OpenBSD: misc.c,v 1.27 2002/04/26 16:15:16 espie Exp $ */
+/* $OpenBSD: misc.c,v 1.42 2010/09/07 19:58:09 marco Exp $ */
/* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */
/*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)misc.c 8.1 (Berkeley) 6/6/93
- * $OpenBSD: misc.c,v 1.27 2002/04/26 16:15:16 espie Exp $
- * $FreeBSD: src/usr.bin/m4/misc.c,v 1.15 2002/07/15 02:15:12 jmallett Exp $
- * $DragonFly: src/usr.bin/m4/misc.c,v 1.3 2006/12/27 21:29:02 pavalos Exp $
+ * $FreeBSD: src/usr.bin/m4/misc.c,v 1.18 2012/11/17 01:54:24 svnexp Exp $
*/
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
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 */
/*
return (t - s1);
}
/*
- * putback - push character back onto input
+ * pushback - push character back onto input
*/
void
-putback(int c)
+pushback(int c)
{
if (c == EOF)
return;
/*
* pbstr - push string back onto input
- * putback is replicated to improve
+ * pushback is replicated to improve
* performance.
*/
void
size_t n;
n = strlen(s);
- while ((size_t)(endpbb - bp) <= n)
+ while (endpbb - bp <= (long)n)
enlarge_bufspace();
while (n > 0)
*bp++ = s[--n];
void
pbnum(int n)
{
+ pbnumbase(n, 10, 0);
+}
+
+void
+pbnumbase(int n, int base, int d)
+{
+ static char digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
int num;
+ int printed = 0;
+
+ if (base > 36)
+ m4errx(1, "base %d > 36: not supported.", base);
+
+ if (base < 2)
+ m4errx(1, "bad base %d for conversion.", base);
num = (n < 0) ? -n : n;
do {
- putback(num % 10 + '0');
+ pushback(digits[num % base]);
+ printed++;
}
- while ((num /= 10) > 0);
+ while ((num /= base) > 0);
+
+ if (n < 0)
+ printed++;
+ while (printed++ < d)
+ pushback('0');
if (n < 0)
- putback('-');
+ pushback('-');
}
/*
pbunsigned(unsigned long n)
{
do {
- putback(n % 10 + '0');
+ pushback(n % 10 + '0');
}
while ((n /= 10) > 0);
}
{
int i;
- strspace = xalloc(strsize+1);
+ strspace = xalloc(strsize + 1, NULL);
ep = strspace;
- endest = strspace+strsize;
- buf = (char *)xalloc(bufsize);
+ endest = strspace + strsize;
+ buf = (unsigned char *)xalloc(bufsize, NULL);
bufbase = buf;
bp = buf;
endpbb = buf + bufsize;
memcpy(newstrspace, strspace, strsize/2);
for (i = 0; i <= sp; i++)
if (sstack[i])
- mstack[i].sstr = (mstack[i].sstr - strspace)
- + newstrspace;
+ mstack[i].sstr = (mstack[i].sstr - strspace) +
+ newstrspace;
ep = (ep-strspace) + newstrspace;
free(strspace);
strspace = newstrspace;
void
enlarge_bufspace(void)
{
- char *newbuf;
+ unsigned char *newbuf;
int i;
- bufsize *= 2;
- newbuf = realloc(buf, bufsize);
- if (!newbuf)
- errx(1, "too many characters pushed back");
+ bufsize += bufsize / 2;
+ newbuf = xrealloc(buf, bufsize, "too many characters pushed back");
for (i = 0; i < MAXINP; i++)
- bbase[i] = (bbase[i]-buf)+newbuf;
- bp = (bp-buf)+newbuf;
- bufbase = (bufbase-buf)+newbuf;
+ bbase[i] = (bbase[i] - buf) + newbuf;
+ bp = (bp - buf) + newbuf;
+ bufbase = (bufbase - buf) + newbuf;
buf = newbuf;
- endpbb = buf+bufsize;
+ endpbb = buf + bufsize;
}
/*
int c;
if (active == outfile[n])
- errx(1, "undivert: diversion still active");
+ m4errx(1, "undivert: diversion still active.");
rewind(outfile[n]);
while ((c = getc(outfile[n])) != EOF)
putc(c, active);
- (void) fclose(outfile[n]);
+ fclose(outfile[n]);
outfile[n] = NULL;
}
onintr(int signo __unused)
{
#define intrmessage "m4: interrupted.\n"
- write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1);
+ write(STDERR_FILENO, intrmessage, sizeof(intrmessage) - 1);
_exit(1);
}
for (n = 0; n < maxout; n++)
if (outfile[n] != NULL) {
- (void) fclose(outfile[n]);
+ fclose(outfile[n]);
}
}
+extern char *__progname;
+
+void
+m4errx(int evaluation, const char *fmt, ...)
+{
+ fprintf(stderr, "%s: ", __progname);
+ fprintf(stderr, "%s at line %lu: ", CURRENT_NAME, CURRENT_LINE);
+ if (fmt != NULL) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+ fprintf(stderr, "\n");
+ exit(evaluation);
+}
+
/*
* resizedivs: allocate more diversion files */
void
{
int i;
- outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n);
- if (outfile == NULL)
- errx(1, "too many diverts %d", n);
+ outfile = (FILE **)xrealloc(outfile, sizeof(FILE *) * n,
+ "too many diverts %d", n);
for (i = maxout; i < n; i++)
outfile[i] = NULL;
maxout = n;
}
void *
-xalloc(size_t n)
+xalloc(size_t n, const char *fmt, ...)
{
- char *p = malloc(n);
+ void *p = malloc(n);
- if (p == NULL)
- err(1, "malloc");
+ if (p == NULL) {
+ if (fmt == NULL)
+ err(1, "malloc");
+ else {
+ va_list va;
+
+ va_start(va, fmt);
+ verr(1, fmt, va);
+ va_end(va);
+ }
+ }
+ return p;
+}
+
+void *
+xrealloc(void *old, size_t n, const char *fmt, ...)
+{
+ char *p = realloc(old, n);
+
+ if (p == NULL) {
+ free(old);
+ if (fmt == NULL)
+ err(1, "realloc");
+ else {
+ va_list va;
+
+ va_start(va, fmt);
+ verr(1, fmt, va);
+ va_end(va);
+ }
+ }
return p;
}
void
usage(void)
{
- fprintf(stderr,
-"usage: m4 [-d flags] [-t name] [-gs] [-D name[=value]]...\n"
-" [-U name]... [-I dirname]... file...\n");
+ fprintf(stderr, "usage: m4 [-gPs] [-Dname[=value]] [-d flags] "
+ "[-I dirname] [-o filename]\n"
+ "\t[-t macro] [-Uname] [file ...]\n");
exit(1);
}
{
if (f->c == EOF)
return EOF;
- else if (f->c == '\n')
- f->lineno++;
f->c = fgetc(f->file);
+ if (f->c == '\n')
+ f->lineno++;
+
return f->c;
}
f->lineno = 1;
f->c = 0;
f->name = xstrdup(name);
+ emit_synchline();
+}
+
+void
+do_emit_synchline(void)
+{
+ fprintf(active, "#line %lu \"%s\"\n",
+ infile[ilevel].lineno, infile[ilevel].name);
+ infile[ilevel].synch_lineno = infile[ilevel].lineno;
}
void
void
dump_buffer(FILE *f, size_t m)
{
- char *s;
+ unsigned char *s;
- for (s = bp; s - buf > (int)m;)
+ for (s = bp; s-buf > (long)m;)
fputc(*--s, f);
}