]> git.ipfire.org Git - thirdparty/gcc.git/blob - texinfo/util/deref.c
Initial revision
[thirdparty/gcc.git] / texinfo / util / deref.c
1 /*
2 * deref.c
3
4 * compile command: gcc -g -o deref deref.c
5
6 * execute command: deref filename.texi > newfile.texi
7
8 * To: bob@gnu.ai.mit.edu
9 * Subject: another tool
10 * Date: 18 Dec 91 16:03:13 EST (Wed)
11 * From: gatech!skeeve!arnold@eddie.mit.edu (Arnold D. Robbins)
12 *
13 * Here is deref.c. It turns texinfo cross references back into the
14 * one argument form. It has the same limitations as fixref; one xref per
15 * line and can't cross lines. You can use it to find references that do
16 * cross a line boundary this way:
17 *
18 * deref < manual > /dev/null 2>errs
19 *
20 * (This assumes bash or /bin/sh.) The file errs will have list of lines
21 * where deref could not find matching braces.
22 *
23 * A gawk manual processed by deref goes through makeinfo without complaint.
24 * Compile with gcc and you should be set.
25 *
26 * Enjoy,
27 *
28 * Arnold
29 * -----------
30 */
31
32 /*
33 * deref.c
34 *
35 * Make all texinfo references into the one argument form.
36 *
37 * Arnold Robbins
38 * arnold@skeeve.atl.ga.us
39 * December, 1991
40 *
41 * Copyright, 1991, Arnold Robbins
42 */
43
44 /*
45 * LIMITATIONS:
46 * One texinfo cross reference per line.
47 * Cross references may not cross newlines.
48 * Use of fgets for input (to be fixed).
49 */
50
51 #include <stdio.h>
52 #include <ctype.h>
53 #include <errno.h>
54
55 /* for gcc on the 3B1, delete if this gives you grief */
56 extern int fclose (FILE * fp);
57 extern int fprintf (FILE * fp, const char *str,...);
58
59 extern char *strerror (int errno);
60 extern char *strchr (char *cp, int ch);
61 extern int strncmp (const char *s1, const char *s2, int count);
62
63 extern int errno;
64
65 void process (FILE * fp);
66 void repair (char *line, char *ref, int toffset);
67
68 int Errs = 0;
69 char *Name = "stdin";
70 int Line = 0;
71 char *Me;
72
73 /* main --- handle arguments, global vars for errors */
74
75 int
76 main (int argc, char **argv)
77 {
78 FILE *fp;
79
80 Me = argv[0];
81
82 if (argc == 1)
83 process (stdin);
84 else
85 for (argc--, argv++; *argv != NULL; argc--, argv++)
86 {
87 if (argv[0][0] == '-' && argv[0][1] == '\0')
88 {
89 Name = "stdin";
90 Line = 0;
91 process (stdin);
92 }
93 else if ((fp = fopen (*argv, "r")) != NULL)
94 {
95 Name = *argv;
96 Line = 0;
97 process (fp);
98 fclose (fp);
99 }
100 else
101 {
102 fprintf (stderr, "%s: can not open: %s\n",
103 *argv, strerror (errno));
104 Errs++;
105 }
106 }
107 return Errs != 0;
108 }
109
110 /* isref --- decide if we've seen a texinfo cross reference */
111
112 int
113 isref (char *cp)
114 {
115 if (strncmp (cp, "@ref{", 5) == 0)
116 return 5;
117 if (strncmp (cp, "@xref{", 6) == 0)
118 return 6;
119 if (strncmp (cp, "@pxref{", 7) == 0)
120 return 7;
121 return 0;
122 }
123
124 /* process --- read files, look for references, fix them up */
125
126 void
127 process (FILE * fp)
128 {
129 char buf[BUFSIZ];
130 char *cp;
131 int count;
132
133 while (fgets (buf, sizeof buf, fp) != NULL)
134 {
135 Line++;
136 cp = strchr (buf, '@');
137 if (cp == NULL)
138 {
139 fputs (buf, stdout);
140 continue;
141 }
142 do
143 {
144 count = isref (cp);
145 if (count == 0)
146 {
147 cp++;
148 cp = strchr (cp, '@');
149 if (cp == NULL)
150 {
151 fputs (buf, stdout);
152 goto next;
153 }
154 continue;
155 }
156 /* got one */
157 repair (buf, cp, count);
158 break;
159 }
160 while (cp != NULL);
161 next:;
162 }
163 }
164
165 /* repair --- turn all texinfo cross references into the one argument form */
166
167 void
168 repair (char *line, char *ref, int toffset)
169 {
170 int braces = 1; /* have seen first left brace */
171 char *cp;
172
173 ref += toffset;
174
175 /* output line up to and including left brace in reference */
176 for (cp = line; cp <= ref; cp++)
177 putchar (*cp);
178
179 /* output node name */
180 for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
181 putchar (*cp);
182
183 if (*cp != '}')
184 { /* could have been one arg xref */
185 /* skip to matching right brace */
186 for (; braces > 0; cp++)
187 {
188 switch (*cp)
189 {
190 case '@':
191 cp++; /* blindly skip next character */
192 break;
193 case '{':
194 braces++;
195 break;
196 case '}':
197 braces--;
198 break;
199 case '\n':
200 case '\0':
201 Errs++;
202 fprintf (stderr,
203 "%s: %s: %d: mismatched braces\n",
204 Me, Name, Line);
205 goto out;
206 default:
207 break;
208 }
209 }
210 out:
211 ;
212 }
213
214 putchar ('}');
215 if (*cp == '}')
216 cp++;
217
218 /* now the rest of the line */
219 for (; *cp; cp++)
220 putchar (*cp);
221 return;
222 }
223
224 /* strerror --- return error string, delete if in your library */
225
226 char *
227 strerror (int errno)
228 {
229 static char buf[100];
230 extern int sys_nerr;
231 extern char *sys_errlist[];
232
233 if (errno < sys_nerr && errno >= 0)
234 return sys_errlist[errno];
235
236 sprintf (buf, "unknown error %d", errno);
237 return buf;
238 }