123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * deref.c
- *
- * Make all texinfo references into the one argument form.
- *
- * Arnold Robbins
- * Written: December, 1991
- * Released: November, 1998
- *
- * Copyright 1991, 1998 Arnold David Robbins
- *
- * DEREF is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DEREF is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /*
- * LIMITATIONS:
- * One texinfo cross reference per line.
- * Cross references may not cross newlines.
- * Use of fgets for input (to be fixed).
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- /* for gcc on the 3B1, delete if this gives you grief */
- extern int fclose(FILE *fp);
- extern int fprintf(FILE *fp, const char *str, ...);
- /* extern int sprintf(char *str, const char *fmt, ...); */
- extern int fputs(char *buf, FILE *fp);
- extern char *strerror(int errno);
- extern char *strchr(char *cp, int ch);
- extern int strncmp(const char *s1, const char *s2, int count);
- extern int errno;
- void process(FILE *fp);
- void repair(char *line, char *ref, int toffset);
- int Errs = 0;
- char *Name = "stdin";
- int Line = 0;
- char *Me;
- /* main --- handle arguments, global vars for errors */
- int
- main(int argc, char **argv)
- {
- FILE *fp;
- Me = argv[0];
- if (argc == 1)
- process(stdin);
- else
- for (argc--, argv++; *argv != NULL; argc--, argv++) {
- if (argv[0][0] == '-' && argv[0][1] == '\0') {
- Name = "stdin";
- Line = 0;
- process(stdin);
- } else if ((fp = fopen(*argv, "r")) != NULL) {
- Name = *argv;
- Line = 0;
- process(fp);
- fclose(fp);
- } else {
- fprintf(stderr, "%s: can not open: %s\n",
- *argv, strerror(errno));
- Errs++;
- }
- }
- return Errs != 0;
- }
- /* isref --- decide if we've seen a texinfo cross reference */
- int
- isref(char *cp)
- {
- if (strncmp(cp, "@ref{", 5) == 0)
- return 5;
- if (strncmp(cp, "@xref{", 6) == 0)
- return 6;
- if (strncmp(cp, "@pxref{", 7) == 0)
- return 7;
- return 0;
- }
- /* process --- read files, look for references, fix them up */
- void
- process(FILE *fp)
- {
- char buf[BUFSIZ];
- char *cp;
- int count;
- while (fgets(buf, sizeof buf, fp) != NULL) {
- Line++;
- cp = strchr(buf, '@');
- if (cp == NULL) {
- fputs(buf, stdout);
- continue;
- }
- do {
- count = isref(cp);
- if (count == 0) {
- cp++;
- cp = strchr(cp, '@');
- if (cp == NULL) {
- fputs(buf, stdout);
- goto next;
- }
- continue;
- }
- /* got one */
- repair(buf, cp, count);
- break;
- } while (cp != NULL);
- next: ;
- }
- }
- /* repair --- turn all texinfo cross references into the one argument form */
- void
- repair(char *line, char *ref, int toffset)
- {
- int braces = 1; /* have seen first left brace */
- char *cp;
- ref += toffset;
- /* output line up to and including left brace in reference */
- for (cp = line; cp <= ref; cp++)
- putchar(*cp);
- /* output node name */
- for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
- putchar(*cp);
- if (*cp != '}') { /* could have been one arg xref */
- /* skip to matching right brace */
- for (; braces > 0; cp++) {
- switch (*cp) {
- case '@':
- cp++; /* blindly skip next character */
- break;
- case '{':
- braces++;
- break;
- case '}':
- braces--;
- break;
- case '\n':
- case '\0':
- Errs++;
- fprintf(stderr,
- "%s: %s: %d: mismatched braces\n",
- Me, Name, Line);
- goto out;
- default:
- break;
- }
- }
- out:
- ;
- }
- putchar('}');
- if (*cp == '}')
- cp++;
- /* now the rest of the line */
- for (; *cp; cp++)
- putchar(*cp);
- return;
- }
- /* strerror --- return error string, delete if in your library */
- char *
- strerror(int errno)
- {
- static char buf[100];
- extern int sys_nerr;
- extern char *sys_errlist[];
- if (errno < sys_nerr && errno >= 0)
- return sys_errlist[errno];
- sprintf(buf, "unknown error %d", errno);
- return buf;
- }
|