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

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