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

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