139864Sbostic /* 239864Sbostic * Copyright (c) 1983 The Regents of the University of California. 339864Sbostic * All rights reserved. 439864Sbostic * 539864Sbostic * This code is derived from software contributed to Berkeley by 639864Sbostic * Asa Romberger and Jerry Berkman. 739864Sbostic * 8*42683Sbostic * %sccs.include.redist.c% 939864Sbostic */ 1039864Sbostic 1139864Sbostic #ifndef lint 1239864Sbostic char copyright[] = 1339864Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 1439864Sbostic All rights reserved.\n"; 1539864Sbostic #endif /* not lint */ 1639864Sbostic 1739864Sbostic #ifndef lint 18*42683Sbostic static char sccsid[] = "@(#)fsplit.c 5.4 (Berkeley) 06/01/90"; 1939864Sbostic #endif /* not lint */ 2039864Sbostic 2138281Sbostic #include <ctype.h> 2238281Sbostic #include <stdio.h> 2338281Sbostic #include <sys/types.h> 2438281Sbostic #include <sys/stat.h> 2538281Sbostic 2638281Sbostic /* 2738281Sbostic * usage: fsplit [-e efile] ... [file] 2838281Sbostic * 2938281Sbostic * split single file containing source for several fortran programs 3038281Sbostic * and/or subprograms into files each containing one 3138281Sbostic * subprogram unit. 3238281Sbostic * each separate file will be named using the corresponding subroutine, 3338281Sbostic * function, block data or program name if one is found; otherwise 3438281Sbostic * the name will be of the form mainNNN.f or blkdtaNNN.f . 3538281Sbostic * If a file of that name exists, it is saved in a name of the 3638281Sbostic * form zzz000.f . 3738281Sbostic * If -e option is used, then only those subprograms named in the -e 3838281Sbostic * option are split off; e.g.: 3938281Sbostic * fsplit -esub1 -e sub2 prog.f 4038281Sbostic * isolates sub1 and sub2 in sub1.f and sub2.f. The space 4138281Sbostic * after -e is optional. 4238281Sbostic * 4338281Sbostic * Modified Feb., 1983 by Jerry Berkman, Computing Services, U.C. Berkeley. 4438281Sbostic * - added comments 4538281Sbostic * - more function types: double complex, character*(*), etc. 4638281Sbostic * - fixed minor bugs 4738281Sbostic * - instead of all unnamed going into zNNN.f, put mains in 4838281Sbostic * mainNNN.f, block datas in blkdtaNNN.f, dups in zzzNNN.f . 4938281Sbostic */ 5038281Sbostic 5138281Sbostic #define BSZ 512 5238281Sbostic char buf[BSZ]; 5338281Sbostic FILE *ifp; 5438281Sbostic char x[]="zzz000.f", 5538281Sbostic mainp[]="main000.f", 5638281Sbostic blkp[]="blkdta000.f"; 5738281Sbostic char *look(), *skiplab(), *functs(); 5838281Sbostic 5938281Sbostic #define TRUE 1 6038281Sbostic #define FALSE 0 6138281Sbostic int extr = FALSE, 6238281Sbostic extrknt = -1, 6338281Sbostic extrfnd[100]; 6438281Sbostic char extrbuf[1000], 6538281Sbostic *extrnames[100]; 6638281Sbostic struct stat sbuf; 6738281Sbostic 6838281Sbostic #define trim(p) while (*p == ' ' || *p == '\t') p++ 6938281Sbostic 7038281Sbostic main(argc, argv) 7138281Sbostic char **argv; 7238281Sbostic { 7338281Sbostic register FILE *ofp; /* output file */ 7438281Sbostic register rv; /* 1 if got card in output file, 0 otherwise */ 7538281Sbostic register char *ptr; 7638281Sbostic int nflag, /* 1 if got name of subprog., 0 otherwise */ 7738281Sbostic retval, 7838281Sbostic i; 7938281Sbostic char name[20], 8038281Sbostic *extrptr = extrbuf; 8138281Sbostic 8238281Sbostic /* scan -e options */ 8338281Sbostic while ( argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e') { 8438281Sbostic extr = TRUE; 8538281Sbostic ptr = argv[1] + 2; 8638281Sbostic if(!*ptr) { 8738281Sbostic argc--; 8838281Sbostic argv++; 8938281Sbostic if(argc <= 1) badparms(); 9038281Sbostic ptr = argv[1]; 9138281Sbostic } 9238281Sbostic extrknt = extrknt + 1; 9338281Sbostic extrnames[extrknt] = extrptr; 9438281Sbostic extrfnd[extrknt] = FALSE; 9538281Sbostic while(*ptr) *extrptr++ = *ptr++; 9638281Sbostic *extrptr++ = 0; 9738281Sbostic argc--; 9838281Sbostic argv++; 9938281Sbostic } 10038281Sbostic 10138281Sbostic if (argc > 2) 10238281Sbostic badparms(); 10338281Sbostic else if (argc == 2) { 10438281Sbostic if ((ifp = fopen(argv[1], "r")) == NULL) { 10538281Sbostic fprintf(stderr, "fsplit: cannot open %s\n", argv[1]); 10638281Sbostic exit(1); 10738281Sbostic } 10838281Sbostic } 10938281Sbostic else 11038281Sbostic ifp = stdin; 11138281Sbostic for(;;) { 11238281Sbostic /* look for a temp file that doesn't correspond to an existing file */ 11338281Sbostic get_name(x, 3); 11438281Sbostic ofp = fopen(x, "w"); 11538281Sbostic nflag = 0; 11638281Sbostic rv = 0; 11738281Sbostic while (getline() > 0) { 11838281Sbostic rv = 1; 11938281Sbostic fprintf(ofp, "%s", buf); 12038281Sbostic if (lend()) /* look for an 'end' statement */ 12138281Sbostic break; 12238281Sbostic if (nflag == 0) /* if no name yet, try and find one */ 12338281Sbostic nflag = lname(name); 12438281Sbostic } 12538281Sbostic fclose(ofp); 12638281Sbostic if (rv == 0) { /* no lines in file, forget the file */ 12738281Sbostic unlink(x); 12838281Sbostic retval = 0; 12938281Sbostic for ( i = 0; i <= extrknt; i++ ) 13038281Sbostic if(!extrfnd[i]) { 13138281Sbostic retval = 1; 13238281Sbostic fprintf( stderr, "fsplit: %s not found\n", 13338281Sbostic extrnames[i]); 13438281Sbostic } 13538281Sbostic exit( retval ); 13638281Sbostic } 13738281Sbostic if (nflag) { /* rename the file */ 13838281Sbostic if(saveit(name)) { 13938281Sbostic if (stat(name, &sbuf) < 0 ) { 14038281Sbostic link(x, name); 14138281Sbostic unlink(x); 14238281Sbostic printf("%s\n", name); 14338281Sbostic continue; 14438281Sbostic } else if (strcmp(name, x) == 0) { 14538281Sbostic printf("%s\n", x); 14638281Sbostic continue; 14738281Sbostic } 14838281Sbostic printf("%s already exists, put in %s\n", name, x); 14938281Sbostic continue; 15038281Sbostic } else 15138281Sbostic unlink(x); 15238281Sbostic continue; 15338281Sbostic } 15438281Sbostic if(!extr) 15538281Sbostic printf("%s\n", x); 15638281Sbostic else 15738281Sbostic unlink(x); 15838281Sbostic } 15938281Sbostic } 16038281Sbostic 16138281Sbostic badparms() 16238281Sbostic { 16338281Sbostic fprintf(stderr, "fsplit: usage: fsplit [-e efile] ... [file] \n"); 16438281Sbostic exit(1); 16538281Sbostic } 16638281Sbostic 16738281Sbostic saveit(name) 16838281Sbostic char *name; 16938281Sbostic { 17038281Sbostic int i; 17138281Sbostic char fname[50], 17238281Sbostic *fptr = fname; 17338281Sbostic 17438281Sbostic if(!extr) return(1); 17538281Sbostic while(*name) *fptr++ = *name++; 17638281Sbostic *--fptr = 0; 17738281Sbostic *--fptr = 0; 17838281Sbostic for ( i=0 ; i<=extrknt; i++ ) 17938281Sbostic if( strcmp(fname, extrnames[i]) == 0 ) { 18038281Sbostic extrfnd[i] = TRUE; 18138281Sbostic return(1); 18238281Sbostic } 18338281Sbostic return(0); 18438281Sbostic } 18538281Sbostic 18638281Sbostic get_name(name, letters) 18738281Sbostic char *name; 18838281Sbostic int letters; 18938281Sbostic { 19038281Sbostic register char *ptr; 19138281Sbostic 19238281Sbostic while (stat(name, &sbuf) >= 0) { 19338281Sbostic for (ptr = name + letters + 2; ptr >= name + letters; ptr--) { 19438281Sbostic (*ptr)++; 19538281Sbostic if (*ptr <= '9') 19638281Sbostic break; 19738281Sbostic *ptr = '0'; 19838281Sbostic } 19938281Sbostic if(ptr < name + letters) { 20038281Sbostic fprintf( stderr, "fsplit: ran out of file names\n"); 20138281Sbostic exit(1); 20238281Sbostic } 20338281Sbostic } 20438281Sbostic } 20538281Sbostic 20638281Sbostic getline() 20738281Sbostic { 20838281Sbostic register char *ptr; 20938281Sbostic 21038281Sbostic for (ptr = buf; ptr < &buf[BSZ]; ) { 21138281Sbostic *ptr = getc(ifp); 21238281Sbostic if (feof(ifp)) 21338281Sbostic return (-1); 21438281Sbostic if (*ptr++ == '\n') { 21538281Sbostic *ptr = 0; 21638281Sbostic return (1); 21738281Sbostic } 21838281Sbostic } 21938281Sbostic while (getc(ifp) != '\n' && feof(ifp) == 0) ; 22038281Sbostic fprintf(stderr, "line truncated to %d characters\n", BSZ); 22138281Sbostic return (1); 22238281Sbostic } 22338281Sbostic 22438281Sbostic /* return 1 for 'end' alone on card (up to col. 72), 0 otherwise */ 22538281Sbostic lend() 22638281Sbostic { 22738281Sbostic register char *p; 22838281Sbostic 22938281Sbostic if ((p = skiplab(buf)) == 0) 23038281Sbostic return (0); 23138281Sbostic trim(p); 23238281Sbostic if (*p != 'e' && *p != 'E') return(0); 23338281Sbostic p++; 23438281Sbostic trim(p); 23538281Sbostic if (*p != 'n' && *p != 'N') return(0); 23638281Sbostic p++; 23738281Sbostic trim(p); 23838281Sbostic if (*p != 'd' && *p != 'D') return(0); 23938281Sbostic p++; 24038281Sbostic trim(p); 24138281Sbostic if (p - buf >= 72 || *p == '\n') 24238281Sbostic return (1); 24338281Sbostic return (0); 24438281Sbostic } 24538281Sbostic 24638281Sbostic /* check for keywords for subprograms 24738281Sbostic return 0 if comment card, 1 if found 24838281Sbostic name and put in arg string. invent name for unnamed 24938281Sbostic block datas and main programs. */ 25038281Sbostic lname(s) 25138281Sbostic char *s; 25238281Sbostic { 25338281Sbostic # define LINESIZE 80 25438281Sbostic register char *ptr, *p, *sptr; 25538281Sbostic char line[LINESIZE], *iptr = line; 25638281Sbostic 25738281Sbostic /* first check for comment cards */ 25838281Sbostic if(buf[0] == 'c' || buf[0] == 'C' || buf[0] == '*') return(0); 25938281Sbostic ptr = buf; 26038281Sbostic while (*ptr == ' ' || *ptr == '\t') ptr++; 26138281Sbostic if(*ptr == '\n') return(0); 26238281Sbostic 26338281Sbostic 26438281Sbostic ptr = skiplab(buf); 26538281Sbostic 26638281Sbostic /* copy to buffer and converting to lower case */ 26738281Sbostic p = ptr; 26838281Sbostic while (*p && p <= &buf[71] ) { 26938281Sbostic *iptr = isupper(*p) ? tolower(*p) : *p; 27038281Sbostic iptr++; 27138281Sbostic p++; 27238281Sbostic } 27338281Sbostic *iptr = '\n'; 27438281Sbostic 27538281Sbostic if ((ptr = look(line, "subroutine")) != 0 || 27638281Sbostic (ptr = look(line, "function")) != 0 || 27738281Sbostic (ptr = functs(line)) != 0) { 27838281Sbostic if(scan_name(s, ptr)) return(1); 27938281Sbostic strcpy( s, x); 28038281Sbostic } else if((ptr = look(line, "program")) != 0) { 28138281Sbostic if(scan_name(s, ptr)) return(1); 28238281Sbostic get_name( mainp, 4); 28338281Sbostic strcpy( s, mainp); 28438281Sbostic } else if((ptr = look(line, "blockdata")) != 0) { 28538281Sbostic if(scan_name(s, ptr)) return(1); 28638281Sbostic get_name( blkp, 6); 28738281Sbostic strcpy( s, blkp); 28838281Sbostic } else if((ptr = functs(line)) != 0) { 28938281Sbostic if(scan_name(s, ptr)) return(1); 29038281Sbostic strcpy( s, x); 29138281Sbostic } else { 29238281Sbostic get_name( mainp, 4); 29338281Sbostic strcpy( s, mainp); 29438281Sbostic } 29538281Sbostic return(1); 29638281Sbostic } 29738281Sbostic 29838281Sbostic scan_name(s, ptr) 29938281Sbostic char *s, *ptr; 30038281Sbostic { 30138281Sbostic char *sptr; 30238281Sbostic 30338281Sbostic /* scan off the name */ 30438281Sbostic trim(ptr); 30538281Sbostic sptr = s; 30638281Sbostic while (*ptr != '(' && *ptr != '\n') { 30738281Sbostic if (*ptr != ' ' && *ptr != '\t') 30838281Sbostic *sptr++ = *ptr; 30938281Sbostic ptr++; 31038281Sbostic } 31138281Sbostic 31238281Sbostic if (sptr == s) return(0); 31338281Sbostic 31438281Sbostic *sptr++ = '.'; 31538281Sbostic *sptr++ = 'f'; 31638281Sbostic *sptr++ = 0; 31738549Sbostic return(1); 31838281Sbostic } 31938281Sbostic 32038281Sbostic char *functs(p) 32138281Sbostic char *p; 32238281Sbostic { 32338281Sbostic register char *ptr; 32438281Sbostic 32538281Sbostic /* look for typed functions such as: real*8 function, 32638281Sbostic character*16 function, character*(*) function */ 32738281Sbostic 32838281Sbostic if((ptr = look(p,"character")) != 0 || 32938281Sbostic (ptr = look(p,"logical")) != 0 || 33038281Sbostic (ptr = look(p,"real")) != 0 || 33138281Sbostic (ptr = look(p,"integer")) != 0 || 33238281Sbostic (ptr = look(p,"doubleprecision")) != 0 || 33338281Sbostic (ptr = look(p,"complex")) != 0 || 33438281Sbostic (ptr = look(p,"doublecomplex")) != 0 ) { 33538281Sbostic while ( *ptr == ' ' || *ptr == '\t' || *ptr == '*' 33638281Sbostic || (*ptr >= '0' && *ptr <= '9') 33738281Sbostic || *ptr == '(' || *ptr == ')') ptr++; 33838281Sbostic ptr = look(ptr,"function"); 33938281Sbostic return(ptr); 34038281Sbostic } 34138281Sbostic else 34238281Sbostic return(0); 34338281Sbostic } 34438281Sbostic 34538281Sbostic /* if first 6 col. blank, return ptr to col. 7, 34638281Sbostic if blanks and then tab, return ptr after tab, 34738281Sbostic else return 0 (labelled statement, comment or continuation */ 34838281Sbostic char *skiplab(p) 34938281Sbostic char *p; 35038281Sbostic { 35138281Sbostic register char *ptr; 35238281Sbostic 35338281Sbostic for (ptr = p; ptr < &p[6]; ptr++) { 35438281Sbostic if (*ptr == ' ') 35538281Sbostic continue; 35638281Sbostic if (*ptr == '\t') { 35738281Sbostic ptr++; 35838281Sbostic break; 35938281Sbostic } 36038281Sbostic return (0); 36138281Sbostic } 36238281Sbostic return (ptr); 36338281Sbostic } 36438281Sbostic 36538281Sbostic /* return 0 if m doesn't match initial part of s; 36638281Sbostic otherwise return ptr to next char after m in s */ 36738281Sbostic char *look(s, m) 36838281Sbostic char *s, *m; 36938281Sbostic { 37038281Sbostic register char *sp, *mp; 37138281Sbostic 37238281Sbostic sp = s; mp = m; 37338281Sbostic while (*mp) { 37438281Sbostic trim(sp); 37538281Sbostic if (*sp++ != *mp++) 37638281Sbostic return (0); 37738281Sbostic } 37838281Sbostic return (sp); 37938281Sbostic } 380