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

Revision 13590, 6.0 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** cxrfilt.c
3**
4** if called with no flags, or with the -c or -s flags, it will
5** separate out integer and floating point constants into
6** their own files, pass char and string constants on through.
7** input: sorted output of docxref, contains identifiers and constants.
8** output: identifiers, char and string constants, depending on flags.
9**      output goes to fmtxref. floats and ints to separate files for sorting.
10**
11** if called with -i or -f option, behavior is to put sorted ints or floats
12** back into their original formats, and then pass the output to fmtxref.
13**
14** originally, there was a separate program to do float and int, but these two
15** have been merged to reduce the total number of programs needed for cxref.
16**
17** Arnold Robbins, Information and Computer Science, Georgia Tech
18**      gatech!arnold
19** Copyright (c) 1984 by Arnold Robbins
20** All rights reserved
21** This program may not be sold, but may be distributed
22** provided this header is included.
23*/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include "constdefs.h"
28
29#define MAXFILE         120
30#define MAXLINE         120
31
32FILE *fp1, *fp2;
33int cflag = 0;
34int sflag = 0;
35char *name;
36
37void outint(char *buf);
38void outfloat(char *buf);
39void usage(void);
40void intfilter(void);
41void floatfilter(void);
42#include "basename.c"
43
44int main(int argc, char **argv)
45{
46        char buf[BUFSIZ];
47        char file1[MAXFILE], file2[MAXFILE];
48        int i;
49
50        name = basename(argv[0]);
51
52        if (argc <= 1)
53                usage();
54
55        if(argv[1][0] == '-')
56        {
57                for (i = 1; argv[1][i] != '\0'; i++)
58                        switch (argv[1][i]) {
59                        case 'c':
60                                cflag = 1;
61                                break;
62
63                        case 's':
64                                sflag = 1;
65                                break;
66
67                        case 'i':
68                                intfilter();
69                                exit(0);
70                                break;
71                       
72                        case 'f':
73                                floatfilter();
74                                exit(0);
75                                break;
76                       
77                        default:        /* bad option given */
78                                usage();
79                                break;
80                        }
81
82                /* if it gets to here, we were called only w/-c or -s */
83                if (argc == 2)
84                        usage();
85
86                argv++;
87        }
88
89        /* code for splitting constants off into separate files */
90
91        sprintf(file1, "/tmp/cxr.%d.1", atoi(argv[1]));
92        sprintf(file2, "/tmp/cxr.%d.2", atoi(argv[1]));
93
94        if ((fp1 = fopen(file1, "w")) == NULL)
95        {
96                fprintf(stderr,"%s: couldn't create tempfile 1\n", name);
97                exit (2);
98        }
99
100        if ((fp2 = fopen(file2, "w")) == NULL)
101        {
102                fprintf(stderr,"%s: couldn't create tempfile 2\n", name);
103                exit (3);
104        }
105
106        while (gets(buf) != NULL)
107        {
108                if (buf[0] != '~')
109                        printf("%s\n", buf);
110                else
111                        switch (buf[1]) {
112                        case CHAR:
113                                if (! cflag)
114                                        printf("%s\n", &buf[2]);
115                                break;
116
117                        case STRING:
118                                if (! sflag)
119                                        printf("%s\n", &buf[2]);
120                                break;
121                       
122                        case INT:
123                                outint(buf);
124                                break;
125                       
126                        case FLOAT:
127                                outfloat(buf);
128                                break;
129                       
130                        default:
131                                fprintf(stderr,"%s: bad input line '%s'\n",
132                                        name, buf);
133                                exit (4);
134                        }
135        }
136
137        fclose(fp1);
138        fclose(fp2);
139
140        return(0);
141}
142
143#define OCTAL   1
144#define HEX     2
145#define DEC     3
146
147void outint(char *buf)
148{
149        char file[MAXLINE], line[MAXLINE];
150        int val;
151        int type = 0;
152
153        buf += 2;               /* skip leading ~INT */
154        file[0] = line[0] = '\0';
155
156        if (buf[0] == '0')      /* octal or hex */
157        {
158                if (buf[1] == 'x' || buf[1] == 'X')     /* hex */
159                {
160                        type = HEX;
161                        buf += 2;       /* skip leading 0x */
162                        sscanf(buf, "%x %s %s", &val, file, line);
163                }
164                else
165                {
166                        type = OCTAL;
167                        sscanf(buf, "%o %s %s", &val, file, line);
168                }
169        }
170        else
171        {
172                type = DEC;
173                sscanf(buf, "%d %s %s", &val, file, line);      /* decimal */
174        }
175
176        /*
177         * strategy is to convert to decimal for numeric sorting,
178         * then have output filter convert back to right base.
179         *
180         * type is used to tell intfilter() what to turn it back into.
181         */
182
183        fprintf(fp1, "%d\t%s\t%s\t%d\n", val, file, line, type);
184}
185
186void outfloat(char *buf)
187{
188        char file[MAXLINE], line[MAXLINE];
189        char mantissa[MAXLINE], exponent[MAXLINE];
190        char strval[MAXLINE];           /* character representation of float */
191        char controlstr[MAXLINE];
192        double val;
193        int i, j;
194
195        buf += 2;       /* skip ~FLOAT */
196
197        mantissa[0] = exponent[0] = file[0] = line[0] = '\0';
198
199        sscanf(buf, "%lf %s %s", &val, file, line);
200
201        for (i = 0; buf[i] != '\t'; i++)
202                if (buf[i] == '.')
203                        break;
204
205        for (j = i + 1; buf[j] != 'E' && buf[j] != 'e' && buf[j] != '\t'; j++)
206                ;
207
208        j -= i - 1;     /* j is now num digits to right decimal point. */
209        if (j < 6)
210                j = 6;  /* default */
211
212        sprintf(controlstr, "%%1.%dg", j);      /* make control string */
213        sprintf(strval, controlstr, val);       /* make character string */
214
215        /*
216         * strategy is a follows:
217         * 1) convert all floats to a common printed format (%g)
218         * 2) split up mantissa and exponent into separate parts for sorting
219         * 3) put them back together later when called w/-f option.
220         */
221
222        for(i = j = 0; strval[j] != 'e' && strval[j] != 'E' && strval[j] != '\0'; i++, j++)
223                mantissa[i] = strval[j];
224        mantissa[i] = '\0';
225
226        if (strval[j] == 'e' || strval[j] == 'E')
227        {
228                j++;
229                for(i = 0; strval[j] != '\0'; i++, j++)
230                        exponent[i] = strval[j];
231                exponent[i] = '\0';
232        }
233        else
234                exponent[0] = '\0';
235       
236        fprintf(fp2, "%s\t%s\t%s\t%s\n", mantissa,
237                exponent[0] != '\0' ? exponent : "0", file, line);
238}
239
240void usage(void)
241{
242        fprintf(stderr, "usage: %s [-csfi] pid\n", name);
243        exit (1);
244}
245
246
247void intfilter(void)    /* put sorted ints back into their original bases */
248{
249        char buf[BUFSIZ];
250        char file[MAXLINE], number[MAXLINE];
251        int val;
252        int type;
253
254        while (gets(buf) != NULL)
255        {
256                sscanf(buf, "%d %s %s %d", &val, file, number, &type);
257
258                switch (type) {
259                case OCTAL:
260                        if (val == 0)           /* don't print 00 */
261                                printf("0\t%s\t%s\n", file, number);
262                        else
263                                printf("0%o\t%s\t%s\n", val, file, number);
264                                /* supply leading 0 */
265                        break;
266
267                case DEC:
268                        printf("%d\t%s\t%s\n", val, file, number);
269                        break;
270               
271                case HEX:
272                        printf("0x%x\t%s\t%s\n", val, file, number);
273                        break;
274               
275                default:
276                        fprintf(stderr,"%s: bad input line '%s'\n", name, buf);
277                        exit (4);
278                }
279        }
280}
281
282void floatfilter(void)  /* put sorted floats back together */
283{
284        char buf[BUFSIZ];
285        char file[MAXLINE], number[MAXLINE];
286        char mantissa[MAXLINE], exponent[MAXLINE];
287
288        while (gets(buf) != NULL)
289        {
290                sscanf(buf, "%s %s %s %s", mantissa, exponent, file, number);
291
292                if (strcmp(exponent, "0") == 0)
293                        printf("%s", mantissa);
294                else
295                        printf("%sE%s", mantissa, exponent);
296               
297                printf("\t%s\t%s\n", file, number);
298        }
299}
Note: See TracBrowser for help on using the repository browser.