301 lines
7.4 KiB
Text
301 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
|