source: trunk/athena/bin/cxref/fmtxref.c @ 13590

Revision 13590, 4.3 KB checked in by danw, 25 years ago (diff)
lots of cleanup, reorg, etc, to make this compile with fewer warnings
  • Property svn:executable set to *
Line 
1/*
2** fmtxref.c
3**
4** format the output of the C cross referencer.
5** this program relies on the fact that its input
6** is sorted and uniq-ed.
7**
8** Arnold Robbins, Information and Computer Science, Georgia Tech
9**      gatech!arnold
10** Copyright (c) 1984 by Arnold Robbins.
11** All rights reserved.
12** This program may not be sold, but may be distributed
13** provided this header is included.
14*/
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <ctype.h>
20
21#define TRUE    1
22#define FALSE   0
23
24#define MAXID   121     /* maximum lengths of identifiers, file names, etc. */
25#define MAXFILE 15
26#define MAXLINE 121
27#define MAXNUM  7
28
29#define ID      1       /* return codes to indicate what is new on input line */
30#define NEWFILE 2
31#define LINE    3
32#define ERROR   4
33
34#define WIDTH   80      /* default line output width */
35
36int width = WIDTH;
37
38char prev_id[MAXID] = "";
39char prev_file[MAXFILE] = "";
40
41char id[MAXID] = "";
42char file[MAXFILE] = "";
43char line[MAXNUM] = "";
44
45char *name;
46
47int breakup(char *text);
48void output(int val);
49void usage(void);
50
51#include "basename.c"
52
53int main(int argc, char **argv)
54{
55        char in_line[BUFSIZ];
56        int val;
57
58        name = basename(argv[0]);
59
60        /*
61         * since this program is ONLY called by the cxref driver,
62         * we know that it will be called "fmtxref -w width"
63         * so we don't have to do complicated argument parsing.
64         * we also know that cxref makes sure we get a valid width.
65         */
66
67        if (argc > 1) {
68                if (argc == 3) {
69                        if (strcmp(argv[1], "-w") == 0)
70                                width = atoi(argv[2]);
71                        else
72                                usage();
73                } else
74                        usage();
75        }
76        /* else
77                use default width */
78
79        if(fgets(in_line, sizeof(in_line), stdin) == NULL)
80        {
81                fprintf(stderr, "%s: standard input is empty.\n", name);
82                exit(1);
83        }
84
85        if((val = breakup(in_line)) == ERROR)
86        {
87                fprintf(stderr, "%s: malformed input '%s'\n", name, in_line);
88                exit(2);
89        }
90
91        output(val);            /* does proper formatting */
92
93        while(fgets(in_line, sizeof(in_line), stdin) != NULL && val != ERROR)
94        {
95                val = breakup(in_line);
96                output(val);
97        }
98
99        if(val == ERROR)
100        {
101                fprintf(stderr, "%s: malformed input '%s'\n", name, in_line);
102                exit(2);
103        }
104
105        putchar('\n');
106        return(0);
107}
108
109int breakup(char *text)
110{
111        int retval;
112        int i, j;
113
114        if(text[0] == '"' || text[0] == '\'')
115        {
116                /* quoted stuff, break the line up by hand */
117
118                i = 0;
119                id[i++] = text[0];
120
121                for(j = 1; text[j] != text[0]; i++, j++)
122                {
123                        id[i] = text[j];
124                        if(id[i] == '\\')
125                                id[++i] = text[++j];    /* e.g. \" */
126                }
127                id[i++] = text[0];
128                id[i] = '\0';
129                j++;    /* skip close quote */
130
131                while(isspace((int)text[j]))
132                        j++;
133               
134                for(i = 0; !isspace((int)text[j]); i++, j++)
135                        file[i] = text[j];
136                file[i] = '\0';
137
138
139                while(isspace((int)text[j]))
140                        j++;
141
142                for(i = 0; !isspace((int)text[j]) && text[j] != '\0'; i++, j++)
143                        line[i] = text[j];
144                line[i] = '\0';
145        }
146        else
147        {
148                if(sscanf(text, "%s %s %s", id, file, line) != 3)
149                        return(ERROR);
150        }
151
152        /* now decide about return code for formatting */
153
154        if(strcmp(prev_id, id) != 0)    /* different identifiers */
155        {
156                strcpy(prev_id, id);
157                strcpy(prev_file, file);
158                retval = ID;
159        }
160        else if(strcmp(prev_file, file) != 0)   /* different files */
161        {
162                strcpy(prev_file, file);
163                retval = NEWFILE;
164        }
165        else
166                retval = LINE;
167
168        return(retval);
169}
170
171void output(int val)
172{
173        static int curpos = 1;
174        static int first = TRUE;
175        int line_len = strlen(line);
176
177        switch(val) {
178        case ID:
179                if(! first)
180                        putchar('\n');  /* finish off last line of prev id */
181                else
182                        first = FALSE;
183
184                printf("%-20.20s\t%-14.14s\t%s", id, file, line);
185                curpos = 40 + line_len;
186                break;
187
188        case NEWFILE:
189                printf("\n\t\t\t%-14.14s\t%s", file, line);
190                curpos = 40 + line_len;
191                break;
192
193        case LINE:
194                if(curpos + line_len + 2 < width)
195                {
196                        printf(", %s", line);   /* same output line */
197                        curpos += 2 + line_len;
198                }
199                else
200                {
201                        printf(",\n\t\t\t\t\t%s", line);        /* new line */
202                        curpos = 40 + line_len;
203                }
204                break;
205
206        case ERROR:
207                /* shouldn't come to here */
208                fprintf(stderr, "%s: internal error: output() called with %s\n",
209                        name, "a value of ERROR");
210                fprintf(stderr, "%s: id == '%s'\tfile == '%s'\tline == '%s'\n",
211                        name, id, file, line);
212                break;
213
214        default:
215                /* shouldn't come to here either */
216                fprintf(stderr, "%s: internal error: output() called with %s %d\n",
217                        name, "the unknown value", val);
218                fprintf(stderr, "%s: id == '%s'\tfile == '%s'\tline == '%s'\n",
219                        name, id, file, line);
220                break;
221        }
222}
223
224void usage(void)
225{
226        fprintf(stderr, "usage: %s [-w width]\n", basename(name));
227        exit (1);
228}
Note: See TracBrowser for help on using the repository browser.