pkgsrc/textproc/texi2roff/patches/patch-af
agc 70f43d63b9 Initial import of texi2roff-2.0 into the NetBSD packages collection.
Provided in PR 13059 by Ben Collver (collver@linuxfreemail.com)

Texi2roff is an unmaintained program program to convert Texinfo to troff.
Beverly Erlebacher wrote the program and made the last release in the late
1980's. William Bader produced a patch in 1996 adding numerous commands and
other functionality. Alain Knaff added a translation table to generate man
pages, and uses it to generate the manuals for mtools.  Ben Collver
integrated William Bader's and Alain Knaff's changes and made minor cleanups.
2001-05-30 11:45:41 +00:00

300 lines
7.4 KiB
Text

$NetBSD: patch-af,v 1.1.1.1 2001/05/30 11:45:41 agc Exp $
--- translate.c.orig Mon May 28 11:39:14 2001
+++ translate.c Mon May 28 12:18:03 2001
@@ -11,6 +11,10 @@
#include <stdio.h>
#include "texi2roff.h"
+#ifndef TDEBUG
+#define TDEBUG 0
+#endif
+
extern int transparent; /* -t flag: dont discard things */
int displaylevel = 0; /* nesting level of 'display' text */
int inmacroarg = NO; /* protect roff macro args flag */
@@ -78,6 +82,9 @@
while (fgets(input, MAXLINELEN, in) != NULL) {
++linecount;
+ if (linecount == 1 && strncmp(input, "\\input texinfo", 14) == 0) {
+ continue;
+ }
inp = input;
*output = 0;
if (*inp == '.') /* protect leading '.' in input */
@@ -118,13 +125,99 @@
}
/*
+ * handle variables
+ */
+
+static struct vartag {
+ char var_name[MAXLINELEN];
+ char var_value[MAXLINELEN + 20]; /* room for no value for ... */
+ int var_is_set;
+ struct vartag *var_next;
+} *first_var = NULL;
+
+/*
+ * lookup a variable and return a pointer to it.
+ * creates the variable if needed.
+ */
+
+static struct vartag *
+lookup_var(name)
+char *name;
+{
+ struct vartag *v;
+
+ for (v = first_var; v; v = v->var_next) {
+ if (strcmp(v->var_name, name) == 0) {
+ return(v);
+ }
+ }
+
+ v = (struct vartag *) malloc(sizeof(struct vartag));
+ if (!v) {
+ errormsg("unable to save variable: ", name);
+ } else {
+ strncpy(v->var_name, name, MAXLINELEN);
+ v->var_name[MAXLINELEN-1] = '\0';
+ v->var_value[0] = '\0';
+ v->var_is_set = NO;
+ v->var_next = first_var;
+ first_var = v;
+ }
+ return(v);
+}
+
+static void
+set_var(name, is_set, value)
+char *name, *value;
+int is_set;
+{
+ struct vartag *v;
+
+ v = lookup_var(name);
+ if (v) {
+ v->var_is_set = is_set;
+ if (is_set) {
+ strncpy(v->var_value, value, MAXLINELEN-1);
+ v->var_value[MAXLINELEN-1] = '\0';
+ } else {
+ v->var_value[0] = '\0';
+ }
+ }
+}
+
+static int
+var_is_set(name)
+char *name;
+{
+ struct vartag *v;
+ v = lookup_var(name);
+ return(v != (struct vartag *)NULL && v->var_is_set);
+}
+
+static char *
+get_var(name)
+char *name;
+{
+ struct vartag *v;
+ v = lookup_var(name);
+ if (!v)
+ return("");
+ if (!v->var_is_set)
+ sprintf(v->var_value, "{No value for \"%s\"}", v->var_name);
+ return(v->var_value);
+}
+
+/*
* PUSH - macro to push pointer to table entry onto command stack
* and current font onto font stack
*/
-#define MAXDEPTH 20
+#define MAXDEPTH 100
#define PUSH(tptr) \
+ if (tptr->texend[0] == '\0') { \
+ errormsg("error - table has empty end for cmd ", tptr->texstart);\
+ } \
if (++stackptr == MAXDEPTH) { \
errormsg("stack overflow - commands nested too deeply", ""); \
return NULL; \
@@ -160,6 +253,13 @@
FILE *fp; /* for @include files */
extern int process(); /* for @include files */
+#if TDEBUG
+ fprintf(stderr,
+ "interp, ln %d token '%s', stackptr %d fontptr %d discard %d level %d inmacarg %d\n",
+ linecount, token, stackptr, fontptr,
+ discarding, discardlevel, inmacroarg);
+#endif
+
if (init == NO) {
(void) strcpy(fontstack[0], defaultfont);
(void) strcpy(curfont, defaultfont);
@@ -169,12 +269,17 @@
s = inp;
if (stackptr > 0 && STREQ(token, stack[stackptr]->texend)) {
/* have fetched closing token of current Texinfo command */
+#if TDEBUG
+ fprintf(stderr, "interp, found end, stackptr %d\n", stackptr);
+#endif
if (STREQ(token, "@end")) {/* WARNING! only works from translate() */
s = gettoken(eatwhitespace(s),tempstr);
- if (! STREQ(&(stack[stackptr]->texstart[1]), tempstr)
- && !discarding) {
+ if (! STREQ(&(stack[stackptr]->texstart[1]), tempstr) ) {
errormsg("unexpected @end found for Texinfo cmd @", tempstr);
- return s;
+ errormsg("expected @end for Texinfo cmd ", stack[stackptr]->texstart);
+ if (!discarding) {
+ return s;
+ }
}
}
if (!discarding)
@@ -209,6 +314,9 @@
return ""; /* flush rest of line if any */
}
} else if (*token != '@') { /* ordinary piece of text */
+#if TDEBUG
+ fprintf(stderr, "interp, normal text\n");
+#endif
if (!discarding)
(void) strcat(outstring, token);
if (*token == '\n') {
@@ -220,10 +328,23 @@
if (!discarding)
errormsg("unrecognized Texinfo command ", token);
} else {
+#if TDEBUG
+ fprintf(stderr, "interp, command, type %d\n", tptr->type);
+#endif
switch (tptr->type) {
case ESCAPED:
- if (!discarding)
- (void) strcat(outstring, tptr->trfstart);
+ if (tptr->texend[0] != '\0') {
+ errormsg("error - table has non-empty end for cmd ",
+ tptr->texstart);
+ }
+ if (!discarding) {
+ if (tptr->trfstart[0] != '\0') {
+ (void) strcat(outstring, tptr->trfstart);
+ }
+ if (tptr->trfend[0] != '\0') {
+ (void) strcat(outstring, tptr->trfend);
+ }
+ }
break;
case DISPLAY:
++displaylevel;
@@ -249,6 +370,16 @@
if (!discarding && !transparent) {
discarding = YES;
discardlevel = stackptr;
+ if (tptr->texend[0] == '\n') {
+ while (*s != '\0' && *s != '\n')
+ s++;
+ }
+ }
+ break;
+ case DISCARDLINE:
+ if (!transparent) {
+ while (*s != '\0' && *s != '\n')
+ s++;
}
break;
case ITEMIZING:
@@ -277,8 +408,7 @@
break;
case END:
s = gettoken(eatwhitespace(s),tempstr);
- if (!discarding)
- errormsg("unexpected @end found for Texinfo cmd @", tempstr);
+ errormsg("unexpected @end found for Texinfo cmd @", tempstr);
break;
case FOOTNOTE:
PUSH(tptr);
@@ -297,11 +427,56 @@
for (cp = tempstr; strchr(" \t\n",*s) == NULL; *cp++ = *s++)
;
*cp = '\0';
- if (!discarding && ( fp = fopen(tempstr, "r")) == NULL)
- errormsg("can't open included file ", tempstr);
- else {
- (void) process(fp, tempstr);
- (void) fclose(fp);
+ if (!discarding) {
+ if ( (fp = fopen(tempstr, "r")) == NULL)
+ errormsg("can't open included file ", tempstr);
+ else {
+ (void) process(fp, tempstr);
+ (void) fclose(fp);
+ }
+ }
+ break;
+ case IFSET:
+ case IFCLEAR:
+ PUSH(tptr);
+ s = eatwhitespace(s);
+ for (cp = tempstr; strchr(" \t\n",*s) == NULL; *cp++ = *s++)
+ ;
+ *cp = '\0';
+ if (!discarding) {
+ discarding = var_is_set(tempstr);
+ if (tptr->type == IFSET) discarding = !discarding;
+ if (discarding) discardlevel = stackptr;
+ }
+ break;
+ case SET:
+ case CLEAR:
+ s = eatwhitespace(s);
+ for (cp = itemtag; strchr(" \t\n",*s) == NULL; *cp++ = *s++)
+ ;
+ *cp = '\0';
+ if (tptr->type == CLEAR) {
+ if (!discarding) {
+ set_var(itemtag, NO, "");
+ }
+ } else {
+ s = eatwhitespace(s);
+ for (cp = s; *s != '\0' && *s != '\n'; s++)
+ ;
+ *s = '\0';
+ if (!discarding) {
+ set_var(itemtag, YES, cp);
+ }
+ }
+ break;
+ case VALUE:
+ cp = tempstr;
+ while (*s != '}' && *s != '\n' && *s != '\0')
+ *cp++ = *s++;
+ *cp = 0;
+ if (*s == '}') s++;
+ if (!discarding) {
+ (void) strcat(outstring, get_var(tempstr));
}
break;
default:
@@ -406,6 +581,13 @@
++s;
break;
case '@':
+ /* handle 3 char @ tokens @ + "'`=^~ + letter */
+ if (s[1] != '\0' &&
+ ((s[2] >= 'a' && s[2] <= 'z') || (s[2] >= 'A' && s[2] <= 'Z')) &&
+ strchr("\"'`=^~", s[1]) != NULL) {
+ s += 2;
+ break;
+ }
s = strpbrk_like(q + 1, endchars );
/* handles 2 char @ tokens: @{ @} @@ @: @. @* */
if ( strchr("{}@:.*", *s) == NULL