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

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