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: 31: FILE *fp1, *fp2; 32: int cflag = 0; 33: int sflag = 0; 34: char *name; 35: char *basename(); 36: 37: main(argc, argv) 38: int argc; 39: char **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: 142: outint(buf) 143: char *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: 182: outfloat(buf) 183: char *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: 237: usage() 238: { 239: fprintf(stderr, "usage: %s [-csfi] pid\n", name); 240: exit (1); 241: } 242: 243: 244: intfilter() /* 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: 279: floatfilter() /* 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"