xref: /csrg-svn/usr.bin/fsplit/fsplit.c (revision 62005)
139864Sbostic /*
2*62005Sbostic  * Copyright (c) 1983, 1993
3*62005Sbostic  *	The Regents of the University of California.  All rights reserved.
439864Sbostic  *
539864Sbostic  * This code is derived from software contributed to Berkeley by
639864Sbostic  * Asa Romberger and Jerry Berkman.
739864Sbostic  *
842683Sbostic  * %sccs.include.redist.c%
939864Sbostic  */
1039864Sbostic 
1139864Sbostic #ifndef lint
12*62005Sbostic static char copyright[] =
13*62005Sbostic "@(#) Copyright (c) 1983, 1993\n\
14*62005Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1539864Sbostic #endif /* not lint */
1639864Sbostic 
1739864Sbostic #ifndef lint
18*62005Sbostic static char sccsid[] = "@(#)fsplit.c	8.1 (Berkeley) 06/06/93";
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 
main(argc,argv)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 
badparms()16138281Sbostic badparms()
16238281Sbostic {
16338281Sbostic 	fprintf(stderr, "fsplit: usage:  fsplit [-e efile] ... [file] \n");
16438281Sbostic 	exit(1);
16538281Sbostic }
16638281Sbostic 
saveit(name)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 
get_name(name,letters)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 
getline()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 */
lend()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.		*/
lname(s)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);
26547260Sbostic 	if (ptr == 0)
26647260Sbostic 		return (0);
26738281Sbostic 
26847260Sbostic 
26938281Sbostic 	/*  copy to buffer and converting to lower case */
27038281Sbostic 	p = ptr;
27138281Sbostic 	while (*p && p <= &buf[71] ) {
27238281Sbostic 	   *iptr = isupper(*p) ? tolower(*p) : *p;
27338281Sbostic 	   iptr++;
27438281Sbostic 	   p++;
27538281Sbostic 	}
27638281Sbostic 	*iptr = '\n';
27738281Sbostic 
27838281Sbostic 	if ((ptr = look(line, "subroutine")) != 0 ||
27938281Sbostic 	    (ptr = look(line, "function")) != 0 ||
28038281Sbostic 	    (ptr = functs(line)) != 0) {
28138281Sbostic 		if(scan_name(s, ptr)) return(1);
28238281Sbostic 		strcpy( s, x);
28338281Sbostic 	} else if((ptr = look(line, "program")) != 0) {
28438281Sbostic 		if(scan_name(s, ptr)) return(1);
28538281Sbostic 		get_name( mainp, 4);
28638281Sbostic 		strcpy( s, mainp);
28738281Sbostic 	} else if((ptr = look(line, "blockdata")) != 0) {
28838281Sbostic 		if(scan_name(s, ptr)) return(1);
28938281Sbostic 		get_name( blkp, 6);
29038281Sbostic 		strcpy( s, blkp);
29138281Sbostic 	} else if((ptr = functs(line)) != 0) {
29238281Sbostic 		if(scan_name(s, ptr)) return(1);
29338281Sbostic 		strcpy( s, x);
29438281Sbostic 	} else {
29538281Sbostic 		get_name( mainp, 4);
29638281Sbostic 		strcpy( s, mainp);
29738281Sbostic 	}
29838281Sbostic 	return(1);
29938281Sbostic }
30038281Sbostic 
scan_name(s,ptr)30138281Sbostic scan_name(s, ptr)
30238281Sbostic char *s, *ptr;
30338281Sbostic {
30438281Sbostic 	char *sptr;
30538281Sbostic 
30638281Sbostic 	/* scan off the name */
30738281Sbostic 	trim(ptr);
30838281Sbostic 	sptr = s;
30938281Sbostic 	while (*ptr != '(' && *ptr != '\n') {
31038281Sbostic 		if (*ptr != ' ' && *ptr != '\t')
31138281Sbostic 			*sptr++ = *ptr;
31238281Sbostic 		ptr++;
31338281Sbostic 	}
31438281Sbostic 
31538281Sbostic 	if (sptr == s) return(0);
31638281Sbostic 
31738281Sbostic 	*sptr++ = '.';
31838281Sbostic 	*sptr++ = 'f';
31938281Sbostic 	*sptr++ = 0;
32038549Sbostic 	return(1);
32138281Sbostic }
32238281Sbostic 
functs(p)32338281Sbostic char *functs(p)
32438281Sbostic char *p;
32538281Sbostic {
32638281Sbostic         register char *ptr;
32738281Sbostic 
32838281Sbostic /*      look for typed functions such as: real*8 function,
32938281Sbostic                 character*16 function, character*(*) function  */
33038281Sbostic 
33138281Sbostic         if((ptr = look(p,"character")) != 0 ||
33238281Sbostic            (ptr = look(p,"logical")) != 0 ||
33338281Sbostic            (ptr = look(p,"real")) != 0 ||
33438281Sbostic            (ptr = look(p,"integer")) != 0 ||
33538281Sbostic            (ptr = look(p,"doubleprecision")) != 0 ||
33638281Sbostic            (ptr = look(p,"complex")) != 0 ||
33738281Sbostic            (ptr = look(p,"doublecomplex")) != 0 ) {
33838281Sbostic                 while ( *ptr == ' ' || *ptr == '\t' || *ptr == '*'
33938281Sbostic 			|| (*ptr >= '0' && *ptr <= '9')
34038281Sbostic 			|| *ptr == '(' || *ptr == ')') ptr++;
34138281Sbostic 		ptr = look(ptr,"function");
34238281Sbostic 		return(ptr);
34338281Sbostic 	}
34438281Sbostic         else
34538281Sbostic                 return(0);
34638281Sbostic }
34738281Sbostic 
34838281Sbostic /* 	if first 6 col. blank, return ptr to col. 7,
34938281Sbostic 	if blanks and then tab, return ptr after tab,
35038281Sbostic 	else return 0 (labelled statement, comment or continuation */
skiplab(p)35138281Sbostic char *skiplab(p)
35238281Sbostic char *p;
35338281Sbostic {
35438281Sbostic 	register char *ptr;
35538281Sbostic 
35638281Sbostic 	for (ptr = p; ptr < &p[6]; ptr++) {
35738281Sbostic 		if (*ptr == ' ')
35838281Sbostic 			continue;
35938281Sbostic 		if (*ptr == '\t') {
36038281Sbostic 			ptr++;
36138281Sbostic 			break;
36238281Sbostic 		}
36338281Sbostic 		return (0);
36438281Sbostic 	}
36538281Sbostic 	return (ptr);
36638281Sbostic }
36738281Sbostic 
36838281Sbostic /* 	return 0 if m doesn't match initial part of s;
36938281Sbostic 	otherwise return ptr to next char after m in s */
look(s,m)37038281Sbostic char *look(s, m)
37138281Sbostic char *s, *m;
37238281Sbostic {
37338281Sbostic 	register char *sp, *mp;
37438281Sbostic 
37538281Sbostic 	sp = s; mp = m;
37638281Sbostic 	while (*mp) {
37738281Sbostic 		trim(sp);
37838281Sbostic 		if (*sp++ != *mp++)
37938281Sbostic 			return (0);
38038281Sbostic 	}
38138281Sbostic 	return (sp);
38238281Sbostic }
383