Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: deref.c,v 1.1.1.1 2016/01/14 00:11:29 christos Exp $	*/
      2 
      3 /*
      4  * deref.c
      5  *
      6  * Make all texinfo references into the one argument form.
      7  *
      8  * Arnold Robbins
      9  * arnold (at) gnu.org
     10  * Written: December, 1991
     11  * Released: November, 1998
     12  *
     13  * Copyright, 1991, 1998 Arnold David Robbins
     14  *
     15  * DEREF is free software; you can redistribute it and/or modify
     16  * it under the terms of the GNU General Public License as published by
     17  * the Free Software Foundation; either version 2 of the License, or
     18  * (at your option) any later version.
     19  *
     20  * DEREF is distributed in the hope that it will be useful,
     21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     23  * GNU General Public License for more details.
     24  *
     25  * You should have received a copy of the GNU General Public License
     26  * along with this program; if not, write to the Free Software
     27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
     28  */
     29 
     30 /*
     31  * LIMITATIONS:
     32  *	One texinfo cross reference per line.
     33  *	Cross references may not cross newlines.
     34  *	Use of fgets for input (to be fixed).
     35  */
     36 
     37 #include <stdio.h>
     38 #include <ctype.h>
     39 #include <errno.h>
     40 
     41 /* for gcc on the 3B1, delete if this gives you grief */
     42 extern int fclose(FILE *fp);
     43 extern int fprintf(FILE *fp, const char *str, ...);
     44 /* extern int sprintf(char *str, const char *fmt, ...); */
     45 extern int fputs(char *buf, FILE *fp);
     46 
     47 extern char *strerror(int errno);
     48 extern char *strchr(char *cp, int ch);
     49 extern int strncmp(const char *s1, const char *s2, int count);
     50 
     51 extern int errno;
     52 
     53 void process(FILE *fp);
     54 void repair(char *line, char *ref, int toffset);
     55 
     56 int Errs = 0;
     57 char *Name = "stdin";
     58 int Line = 0;
     59 char *Me;
     60 
     61 /* main --- handle arguments, global vars for errors */
     62 
     63 int
     64 main(int argc, char **argv)
     65 {
     66 	FILE *fp;
     67 
     68 	Me = argv[0];
     69 
     70 	if (argc == 1)
     71 		process(stdin);
     72 	else
     73 		for (argc--, argv++; *argv != NULL; argc--, argv++) {
     74 			if (argv[0][0] == '-' && argv[0][1] == '\0') {
     75 				Name = "stdin";
     76 				Line = 0;
     77 				process(stdin);
     78 			} else if ((fp = fopen(*argv, "r")) != NULL) {
     79 				Name = *argv;
     80 				Line = 0;
     81 				process(fp);
     82 				fclose(fp);
     83 			} else {
     84 				fprintf(stderr, "%s: can not open: %s\n",
     85 					*argv, strerror(errno));
     86 				Errs++;
     87 			}
     88 		}
     89 	return Errs != 0;
     90 }
     91 
     92 /* isref --- decide if we've seen a texinfo cross reference */
     93 
     94 int
     95 isref(char *cp)
     96 {
     97 	if (strncmp(cp, "@ref{", 5) == 0)
     98 		return 5;
     99 	if (strncmp(cp, "@xref{", 6) == 0)
    100 		return 6;
    101 	if (strncmp(cp, "@pxref{", 7) == 0)
    102 		return 7;
    103 	return 0;
    104 }
    105 
    106 /* process --- read files, look for references, fix them up */
    107 
    108 void
    109 process(FILE *fp)
    110 {
    111 	char buf[BUFSIZ];
    112 	char *cp;
    113 	int count;
    114 
    115 	while (fgets(buf, sizeof buf, fp) != NULL) {
    116 		Line++;
    117 		cp = strchr(buf, '@');
    118 		if (cp == NULL) {
    119 			fputs(buf, stdout);
    120 			continue;
    121 		}
    122 		do {
    123 			count = isref(cp);
    124 			if (count == 0) {
    125 				cp++;
    126 				cp = strchr(cp, '@');
    127 				if (cp == NULL) {
    128 					fputs(buf, stdout);
    129 					goto next;
    130 				}
    131 				continue;
    132 			}
    133 			/* got one */
    134 			repair(buf, cp, count);
    135 			break;
    136 		} while (cp != NULL);
    137 	next: ;
    138 	}
    139 }
    140 
    141 /* repair --- turn all texinfo cross references into the one argument form */
    142 
    143 void
    144 repair(char *line, char *ref, int toffset)
    145 {
    146 	int braces = 1;		/* have seen first left brace */
    147 	char *cp;
    148 
    149 	ref += toffset;
    150 
    151 	/* output line up to and including left brace in reference */
    152 	for (cp = line; cp <= ref; cp++)
    153 		putchar(*cp);
    154 
    155 	/* output node name */
    156 	for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
    157 		putchar(*cp);
    158 
    159 	if (*cp != '}')	{	/* could have been one arg xref */
    160 		/* skip to matching right brace */
    161 		for (; braces > 0; cp++) {
    162 			switch (*cp) {
    163 			case '@':
    164 				cp++;	/* blindly skip next character */
    165 				break;
    166 			case '{':
    167 				braces++;
    168 				break;
    169 			case '}':
    170 				braces--;
    171 				break;
    172 			case '\n':
    173 			case '\0':
    174 				Errs++;
    175 				fprintf(stderr,
    176 					"%s: %s: %d: mismatched braces\n",
    177 					Me, Name, Line);
    178 				goto out;
    179 			default:
    180 				break;
    181 			}
    182 		}
    183 	out:
    184 		;
    185 	}
    186 
    187 	putchar('}');
    188 	if (*cp == '}')
    189 		cp++;
    190 
    191 	/* now the rest of the line */
    192 	for (; *cp; cp++)
    193 		putchar(*cp);
    194 	return;
    195 }
    196 
    197 /* strerror --- return error string, delete if in your library */
    198 
    199 char *
    200 strerror(int errno)
    201 {
    202 	static char buf[100];
    203 	extern int sys_nerr;
    204 	extern char *sys_errlist[];
    205 
    206 	if (errno < sys_nerr && errno >= 0)
    207 		return sys_errlist[errno];
    208 
    209 	sprintf(buf, "unknown error %d", errno);
    210 	return buf;
    211 }
    212