|
|
1.1 ! root 1: #include <ctype.h> ! 2: #include <stdio.h> ! 3: #include <sys/types.h> ! 4: #include <sys/stat.h> ! 5: ! 6: /* ! 7: * usage: fsplit [-e efile] ... [file] ! 8: * ! 9: * split single file containing source for several fortran programs ! 10: * and/or subprograms into files each containing one ! 11: * subprogram unit. ! 12: * each separate file will be named using the corresponding subroutine, ! 13: * function, block data or program name if one is found; otherwise ! 14: * the name will be of the form mainNNN.f or blkdtaNNN.f . ! 15: * If a file of that name exists, it is saved in a name of the ! 16: * form zzz000.f . ! 17: * If -e option is used, then only those subprograms named in the -e ! 18: * option are split off; e.g.: ! 19: * fsplit -esub1 -e sub2 prog.f ! 20: * isolates sub1 and sub2 in sub1.f and sub2.f. The space ! 21: * after -e is optional. ! 22: * ! 23: * Modified Feb., 1983 by Jerry Berkman, Computing Services, U.C. Berkeley. ! 24: * - added comments ! 25: * - more function types: double complex, character*(*), etc. ! 26: * - fixed minor bugs ! 27: * - instead of all unnamed going into zNNN.f, put mains in ! 28: * mainNNN.f, block datas in blkdtaNNN.f, dups in zzzNNN.f . ! 29: */ ! 30: ! 31: #define BSZ 512 ! 32: char buf[BSZ]; ! 33: FILE *ifp; ! 34: char x[]="zzz000.f", ! 35: mainp[]="main000.f", ! 36: blkp[]="blkdta000.f"; ! 37: char *look(), *skiplab(), *functs(); ! 38: ! 39: #define TRUE 1 ! 40: #define FALSE 0 ! 41: int extr = FALSE, ! 42: extrknt = -1, ! 43: extrfnd[100]; ! 44: char extrbuf[1000], ! 45: *extrnames[100]; ! 46: struct stat sbuf; ! 47: ! 48: #define trim(p) while (*p == ' ' || *p == '\t') p++ ! 49: ! 50: main(argc, argv) ! 51: char **argv; ! 52: { ! 53: register FILE *ofp; /* output file */ ! 54: register rv; /* 1 if got card in output file, 0 otherwise */ ! 55: register char *ptr; ! 56: int nflag, /* 1 if got name of subprog., 0 otherwise */ ! 57: retval, ! 58: i; ! 59: char name[20], ! 60: *extrptr = extrbuf; ! 61: ! 62: /* scan -e options */ ! 63: while ( argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e') { ! 64: extr = TRUE; ! 65: ptr = argv[1] + 2; ! 66: if(!*ptr) { ! 67: argc--; ! 68: argv++; ! 69: if(argc <= 1) badparms(); ! 70: ptr = argv[1]; ! 71: } ! 72: extrknt = extrknt + 1; ! 73: extrnames[extrknt] = extrptr; ! 74: extrfnd[extrknt] = FALSE; ! 75: while(*ptr) *extrptr++ = *ptr++; ! 76: *extrptr++ = 0; ! 77: argc--; ! 78: argv++; ! 79: } ! 80: ! 81: if (argc > 2) ! 82: badparms(); ! 83: else if (argc == 2) { ! 84: if ((ifp = fopen(argv[1], "r")) == NULL) { ! 85: fprintf(stderr, "fsplit: cannot open %s\n", argv[1]); ! 86: exit(1); ! 87: } ! 88: } ! 89: else ! 90: ifp = stdin; ! 91: for(;;) { ! 92: /* look for a temp file that doesn't correspond to an existing file */ ! 93: get_name(x, 3); ! 94: ofp = fopen(x, "w"); ! 95: nflag = 0; ! 96: rv = 0; ! 97: while (getline() > 0) { ! 98: rv = 1; ! 99: fprintf(ofp, "%s", buf); ! 100: if (lend()) /* look for an 'end' statement */ ! 101: break; ! 102: if (nflag == 0) /* if no name yet, try and find one */ ! 103: nflag = lname(name); ! 104: } ! 105: fclose(ofp); ! 106: if (rv == 0) { /* no lines in file, forget the file */ ! 107: unlink(x); ! 108: retval = 0; ! 109: for ( i = 0; i <= extrknt; i++ ) ! 110: if(!extrfnd[i]) { ! 111: retval = 1; ! 112: fprintf( stderr, "fsplit: %s not found\n", ! 113: extrnames[i]); ! 114: } ! 115: exit( retval ); ! 116: } ! 117: if (nflag) { /* rename the file */ ! 118: if(saveit(name)) { ! 119: if (stat(name, &sbuf) < 0 ) { ! 120: link(x, name); ! 121: unlink(x); ! 122: printf("%s\n", name); ! 123: continue; ! 124: } else if (strcmp(name, x) == 0) { ! 125: printf("%s\n", x); ! 126: continue; ! 127: } ! 128: printf("%s already exists, put in %s\n", name, x); ! 129: continue; ! 130: } else ! 131: unlink(x); ! 132: continue; ! 133: } ! 134: if(!extr) ! 135: printf("%s\n", x); ! 136: else ! 137: unlink(x); ! 138: } ! 139: } ! 140: ! 141: badparms() ! 142: { ! 143: fprintf(stderr, "fsplit: usage: fsplit [-e efile] ... [file] \n"); ! 144: exit(1); ! 145: } ! 146: ! 147: saveit(name) ! 148: char *name; ! 149: { ! 150: int i; ! 151: char fname[50], ! 152: *fptr = fname; ! 153: ! 154: if(!extr) return(1); ! 155: while(*name) *fptr++ = *name++; ! 156: *--fptr = 0; ! 157: *--fptr = 0; ! 158: for ( i=0 ; i<=extrknt; i++ ) ! 159: if( strcmp(fname, extrnames[i]) == 0 ) { ! 160: extrfnd[i] = TRUE; ! 161: return(1); ! 162: } ! 163: return(0); ! 164: } ! 165: ! 166: get_name(name, letters) ! 167: char *name; ! 168: int letters; ! 169: { ! 170: register char *ptr; ! 171: ! 172: while (stat(name, &sbuf) >= 0) { ! 173: for (ptr = name + letters + 2; ptr >= name + letters; ptr--) { ! 174: (*ptr)++; ! 175: if (*ptr <= '9') ! 176: break; ! 177: *ptr = '0'; ! 178: } ! 179: if(ptr < name + letters) { ! 180: fprintf( stderr, "fsplit: ran out of file names\n"); ! 181: exit(1); ! 182: } ! 183: } ! 184: } ! 185: ! 186: getline() ! 187: { ! 188: register char *ptr; ! 189: ! 190: for (ptr = buf; ptr < &buf[BSZ]; ) { ! 191: *ptr = getc(ifp); ! 192: if (feof(ifp)) ! 193: return (-1); ! 194: if (*ptr++ == '\n') { ! 195: *ptr = 0; ! 196: return (1); ! 197: } ! 198: } ! 199: while (getc(ifp) != '\n' && feof(ifp) == 0) ; ! 200: fprintf(stderr, "line truncated to %d characters\n", BSZ); ! 201: return (1); ! 202: } ! 203: ! 204: /* return 1 for 'end' alone on card (up to col. 72), 0 otherwise */ ! 205: lend() ! 206: { ! 207: register char *p; ! 208: ! 209: if ((p = skiplab(buf)) == 0) ! 210: return (0); ! 211: trim(p); ! 212: if (*p != 'e' && *p != 'E') return(0); ! 213: p++; ! 214: trim(p); ! 215: if (*p != 'n' && *p != 'N') return(0); ! 216: p++; ! 217: trim(p); ! 218: if (*p != 'd' && *p != 'D') return(0); ! 219: p++; ! 220: trim(p); ! 221: if (p - buf >= 72 || *p == '\n') ! 222: return (1); ! 223: return (0); ! 224: } ! 225: ! 226: /* check for keywords for subprograms ! 227: return 0 if comment card, 1 if found ! 228: name and put in arg string. invent name for unnamed ! 229: block datas and main programs. */ ! 230: lname(s) ! 231: char *s; ! 232: { ! 233: # define LINESIZE 80 ! 234: register char *ptr, *p, *sptr; ! 235: char line[LINESIZE], *iptr = line; ! 236: ! 237: /* first check for comment cards */ ! 238: if(buf[0] == 'c' || buf[0] == 'C' || buf[0] == '*') return(0); ! 239: ptr = buf; ! 240: while (*ptr == ' ' || *ptr == '\t') ptr++; ! 241: if(*ptr == '\n') return(0); ! 242: ! 243: ! 244: ptr = skiplab(buf); ! 245: ! 246: /* copy to buffer and converting to lower case */ ! 247: p = ptr; ! 248: while (*p && p <= &buf[71] ) { ! 249: *iptr = isupper(*p) ? tolower(*p) : *p; ! 250: iptr++; ! 251: p++; ! 252: } ! 253: *iptr = '\n'; ! 254: ! 255: if ((ptr = look(line, "subroutine")) != 0 || ! 256: (ptr = look(line, "function")) != 0 || ! 257: (ptr = functs(line)) != 0) { ! 258: if(scan_name(s, ptr)) return(1); ! 259: strcpy( s, x); ! 260: } else if((ptr = look(line, "program")) != 0) { ! 261: if(scan_name(s, ptr)) return(1); ! 262: get_name( mainp, 4); ! 263: strcpy( s, mainp); ! 264: } else if((ptr = look(line, "blockdata")) != 0) { ! 265: if(scan_name(s, ptr)) return(1); ! 266: get_name( blkp, 6); ! 267: strcpy( s, blkp); ! 268: } else if((ptr = functs(line)) != 0) { ! 269: if(scan_name(s, ptr)) return(1); ! 270: strcpy( s, x); ! 271: } else { ! 272: get_name( mainp, 4); ! 273: strcpy( s, mainp); ! 274: } ! 275: return(1); ! 276: } ! 277: ! 278: ! 279: scan_name(s, ptr) ! 280: char *s, *ptr; ! 281: { ! 282: char *sptr; ! 283: ! 284: /* scan off the name */ ! 285: trim(ptr); ! 286: sptr = s; ! 287: while (*ptr != '(' && *ptr != '\n') { ! 288: if (*ptr != ' ' && *ptr != '\t') ! 289: *sptr++ = *ptr; ! 290: ptr++; ! 291: } ! 292: ! 293: if (sptr == s) return(0); ! 294: ! 295: *sptr++ = '.'; ! 296: *sptr++ = 'f'; ! 297: *sptr++ = 0; ! 298: } ! 299: ! 300: char *functs(p) ! 301: char *p; ! 302: { ! 303: register char *ptr; ! 304: ! 305: /* look for typed functions such as: real*8 function, ! 306: character*16 function, character*(*) function */ ! 307: ! 308: if((ptr = look(p,"character")) != 0 || ! 309: (ptr = look(p,"logical")) != 0 || ! 310: (ptr = look(p,"real")) != 0 || ! 311: (ptr = look(p,"integer")) != 0 || ! 312: (ptr = look(p,"doubleprecision")) != 0 || ! 313: (ptr = look(p,"complex")) != 0 || ! 314: (ptr = look(p,"doublecomplex")) != 0 ) { ! 315: while ( *ptr == ' ' || *ptr == '\t' || *ptr == '*' ! 316: || (*ptr >= '0' && *ptr <= '9') ! 317: || *ptr == '(' || *ptr == ')') ptr++; ! 318: ptr = look(ptr,"function"); ! 319: return(ptr); ! 320: } ! 321: else ! 322: return(0); ! 323: } ! 324: ! 325: /* if first 6 col. blank, return ptr to col. 7, ! 326: if blanks and then tab, return ptr after tab, ! 327: else return 0 (labelled statement, comment or continuation */ ! 328: char *skiplab(p) ! 329: char *p; ! 330: { ! 331: register char *ptr; ! 332: ! 333: for (ptr = p; ptr < &p[6]; ptr++) { ! 334: if (*ptr == ' ') ! 335: continue; ! 336: if (*ptr == '\t') { ! 337: ptr++; ! 338: break; ! 339: } ! 340: return (0); ! 341: } ! 342: return (ptr); ! 343: } ! 344: ! 345: /* return 0 if m doesn't match initial part of s; ! 346: otherwise return ptr to next char after m in s */ ! 347: char *look(s, m) ! 348: char *s, *m; ! 349: { ! 350: register char *sp, *mp; ! 351: ! 352: sp = s; mp = m; ! 353: while (*mp) { ! 354: trim(sp); ! 355: if (*sp++ != *mp++) ! 356: return (0); ! 357: } ! 358: return (sp); ! 359: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.