* Copyright (c) 1983 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Asa Romberger and Jerry Berkman.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)fsplit.c 5.5 (Berkeley) %G%";
* usage: fsplit [-e efile] ... [file]
* split single file containing source for several fortran programs
* and/or subprograms into files each containing one
* each separate file will be named using the corresponding subroutine,
* function, block data or program name if one is found; otherwise
* the name will be of the form mainNNN.f or blkdtaNNN.f .
* If a file of that name exists, it is saved in a name of the
* If -e option is used, then only those subprograms named in the -e
* option are split off; e.g.:
* fsplit -esub1 -e sub2 prog.f
* isolates sub1 and sub2 in sub1.f and sub2.f. The space
* Modified Feb., 1983 by Jerry Berkman, Computing Services, U.C. Berkeley.
* - more function types: double complex, character*(*), etc.
* - instead of all unnamed going into zNNN.f, put mains in
* mainNNN.f, block datas in blkdtaNNN.f, dups in zzzNNN.f .
char *look(), *skiplab(), *functs();
#define trim(p) while (*p == ' ' || *p == '\t') p++
register FILE *ofp
; /* output file */
register rv
; /* 1 if got card in output file, 0 otherwise */
int nflag
, /* 1 if got name of subprog., 0 otherwise */
while ( argc
> 1 && argv
[1][0] == '-' && argv
[1][1] == 'e') {
if(argc
<= 1) badparms();
extrnames
[extrknt
] = extrptr
;
extrfnd
[extrknt
] = FALSE
;
while(*ptr
) *extrptr
++ = *ptr
++;
if ((ifp
= fopen(argv
[1], "r")) == NULL
) {
fprintf(stderr
, "fsplit: cannot open %s\n", argv
[1]);
/* look for a temp file that doesn't correspond to an existing file */
if (lend()) /* look for an 'end' statement */
if (nflag
== 0) /* if no name yet, try and find one */
if (rv
== 0) { /* no lines in file, forget the file */
for ( i
= 0; i
<= extrknt
; i
++ )
fprintf( stderr
, "fsplit: %s not found\n",
if (nflag
) { /* rename the file */
if (stat(name
, &sbuf
) < 0 ) {
} else if (strcmp(name
, x
) == 0) {
printf("%s already exists, put in %s\n", name
, x
);
fprintf(stderr
, "fsplit: usage: fsplit [-e efile] ... [file] \n");
while(*name
) *fptr
++ = *name
++;
for ( i
=0 ; i
<=extrknt
; i
++ )
if( strcmp(fname
, extrnames
[i
]) == 0 ) {
while (stat(name
, &sbuf
) >= 0) {
for (ptr
= name
+ letters
+ 2; ptr
>= name
+ letters
; ptr
--) {
if(ptr
< name
+ letters
) {
fprintf( stderr
, "fsplit: ran out of file names\n");
for (ptr
= buf
; ptr
< &buf
[BSZ
]; ) {
while (getc(ifp
) != '\n' && feof(ifp
) == 0) ;
fprintf(stderr
, "line truncated to %d characters\n", BSZ
);
/* return 1 for 'end' alone on card (up to col. 72), 0 otherwise */
if ((p
= skiplab(buf
)) == 0)
if (*p
!= 'e' && *p
!= 'E') return(0);
if (*p
!= 'n' && *p
!= 'N') return(0);
if (*p
!= 'd' && *p
!= 'D') return(0);
if (p
- buf
>= 72 || *p
== '\n')
/* check for keywords for subprograms
return 0 if comment card, 1 if found
name and put in arg string. invent name for unnamed
block datas and main programs. */
register char *ptr
, *p
, *sptr
;
char line
[LINESIZE
], *iptr
= line
;
/* first check for comment cards */
if(buf
[0] == 'c' || buf
[0] == 'C' || buf
[0] == '*') return(0);
while (*ptr
== ' ' || *ptr
== '\t') ptr
++;
if(*ptr
== '\n') return(0);
/* copy to buffer and converting to lower case */
while (*p
&& p
<= &buf
[71] ) {
*iptr
= isupper(*p
) ? tolower(*p
) : *p
;
if ((ptr
= look(line
, "subroutine")) != 0 ||
(ptr
= look(line
, "function")) != 0 ||
(ptr
= functs(line
)) != 0) {
if(scan_name(s
, ptr
)) return(1);
} else if((ptr
= look(line
, "program")) != 0) {
if(scan_name(s
, ptr
)) return(1);
} else if((ptr
= look(line
, "blockdata")) != 0) {
if(scan_name(s
, ptr
)) return(1);
} else if((ptr
= functs(line
)) != 0) {
if(scan_name(s
, ptr
)) return(1);
while (*ptr
!= '(' && *ptr
!= '\n') {
if (*ptr
!= ' ' && *ptr
!= '\t')
if (sptr
== s
) return(0);
/* look for typed functions such as: real*8 function,
character*16 function, character*(*) function */
if((ptr
= look(p
,"character")) != 0 ||
(ptr
= look(p
,"logical")) != 0 ||
(ptr
= look(p
,"real")) != 0 ||
(ptr
= look(p
,"integer")) != 0 ||
(ptr
= look(p
,"doubleprecision")) != 0 ||
(ptr
= look(p
,"complex")) != 0 ||
(ptr
= look(p
,"doublecomplex")) != 0 ) {
while ( *ptr
== ' ' || *ptr
== '\t' || *ptr
== '*'
|| (*ptr
>= '0' && *ptr
<= '9')
|| *ptr
== '(' || *ptr
== ')') ptr
++;
ptr
= look(ptr
,"function");
/* if first 6 col. blank, return ptr to col. 7,
if blanks and then tab, return ptr after tab,
else return 0 (labelled statement, comment or continuation */
for (ptr
= p
; ptr
< &p
[6]; ptr
++) {
/* return 0 if m doesn't match initial part of s;
otherwise return ptr to next char after m in s */