Mercurial > hg > xemacs-beta
comparison man/deref.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
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 } |