home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
net
/
prep.2
< prev
next >
Wrap
Internet Message Format
|
1986-12-17
|
55KB
From prove@batcomputer.tn.cornell.edu Tue Dec 16 13:57:45 1986
Path: beno!seismo!rochester!cornell!batcomputer!prove
From: prove@batcomputer.tn.cornell.edu (Roger Ove)
Newsgroups: net.sources
Subject: PREP: fortran preprocessor, part 2/2
Keywords: fortran, preprocessor, cray
Message-ID: <1841@batcomputer.tn.cornell.edu>
Date: 16 Dec 86 18:57:45 GMT
Organization: Theory Center, Cornell U., Ithaca NY
Lines: 2223
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by newton!ove on Mon Dec 15 21:11:16 CST 1986
# Contents: flow.c misc.c fix.h macro.h prep.h prepdf.h prepmac.h string.h
# vecdem.h demo.p sieve.p vecdem.p vecdemo.p
echo x - flow.c
sed 's/^@//' > "flow.c" <<'@//E*O*F flow.c//'
/* Flow control extensions and related routines */
#include "prep.h"
/* Function AGAIN_PROC
*
* Process again statements.
* 3/2/86
*/
again_proc()
{
/* on missing begin statement, abort */
if ( begin_count <= 0 ) {
sprintf( errline, "Again: no matching begin: %s", in_buff ) ;
abort( errline ) ;
}
/* construct the goto statement back to begin */
sprintf( out_buff, " goto %s", blabel[begin_count] ) ;
dump( out_buff ) ;
/* construct label statement */
sprintf( out_buff, "%s continue", alabel[begin_count] ) ;
dump( out_buff ) ;
begin_count-- ;
IN_BUFF_DONE
}
/* Function BEGIN_PROC.C
*
* Process begin statements. Construct a label for the
* while, until, and again statements to branch to. The
* label for again is created here as well.
*
* P. R. OVE 3/2/86
*/
begin_proc()
{
int count ;
/* keep track of the nesting */
begin_count++ ;
if ( begin_count >= NESTING ) {
sprintf( errline, "Begin: nesting too deep: %s", in_buff ) ;
abort( errline ) ;
}
/* make up a label (for begin) and store it in blabel[begin_count] */
count = 17500 + blabel_count ;
blabel_count++ ;
if ( count > 19999 ) {
sprintf( errline, "Begin: too many labels: %s", in_buff ) ;
abort( errline ) ;
}
sprintf( blabel[begin_count], "%d", count ) ;
/* make up a label (for again) and store it in alabel[begin_count] */
count = 15000 + alabel_count ;
alabel_count++ ;
if ( count > 17499 ) {
sprintf( errline, "Begin: too many labels: %s", in_buff ) ;
abort( errline ) ;
}
sprintf( alabel[begin_count], "%d", count ) ;
/* construct and dump the output record */
sprintf( out_buff, "%s continue", blabel[begin_count] ) ;
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function CASE_PROC
*
* Process again statements.
* 11/9/85
*/
case_proc()
{
int n, count ;
char *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if char after case is not a blank, tab, or delimeter assume a */
/* variable name beginning with case */
if ((close_parens == NULL) & (open_parens == first_nonblank + name_length))
return ;
/* keep track of the nesting */
case_count++ ;
if ( case_count >= NESTING ) {
sprintf( errline, "Case: nesting too deep: %s", in_buff ) ;
abort( errline ) ;
}
/* get logical expression, set to NULL if it is missing */
if ( open_parens == NULL ) {
case_exp[ case_count ][0] = NULL ;
}
else {
if ( close_parens == NULL ) {
sprintf( errline, "Case: missing delimeter: %s", in_buff ) ;
abort( errline ) ;
}
n = close_parens - open_parens - 1 ;
GET_MEM( case_exp[case_count], n+5 ) ;
case_exp[case_count][0] = '(' ;
strncpy( case_exp[case_count] + 1, open_parens + 1, n ) ;
case_exp[case_count][n+1] = ')' ;
case_exp[case_count][n+2] = NULL ;
}
/* make label for continue to return to, store it in clabel[case_count] */
count = 20000 + clabel_count ;
clabel_count++ ;
if ( count > 22499 ) {
sprintf( errline, "Case: too many labels: %s", in_buff ) ;
abort( errline ) ;
}
sprintf( clabel[case_count], "%d", count ) ;
/* construct and dump the output record */
sprintf( out_buff, "%s continue", clabel[case_count] ) ;
dump( out_buff ) ;
/* signal that in_buff is empty */
IN_BUFF_DONE
}
/* Function CONTINUE_CASE_PROC
*
* Process continue_case statements (part of case construct).
*
* P. R. OVE 10/10/86
*/
continue_case_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if there is stuff on the line (open_parens != NULL) and no open
* parens (close_parens == NULL) assume variable name */
if ( (open_parens != NULL) & (close_parens == NULL) ) return ;
/* on missing case statement, abort */
if ( case_count <= 0 ) {
sprintf( errline, "CONTINUE_CASE: no matching CASE: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression if there is one */
if (open_parens != NULL) {
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
}
/* construct and dump the jump back to the case statement */
if (open_parens != NULL) {
strcpy( out_buff, " if " ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, " goto " ) ;
strcat( out_buff, clabel[case_count] ) ;
free( exp ) ;
}
else {
strcpy( out_buff, " goto " ) ;
strcat( out_buff, clabel[case_count] ) ;
}
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function CONTINUE_DO_PROC
*
* Process continue_do statements (part of do/end_do construct).
*
* P. R. OVE 11/13/86
*/
continue_do_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if there is stuff on the line (open_parens != NULL) and no open
* parens (close_parens == NULL) assume variable name like CONTINUE_DOit */
if ( (open_parens != NULL) & (close_parens == NULL) ) return ;
/* on missing do statement, abort */
if ( do_count <= 0 ) {
sprintf( errline, "CONTINUE_DO: not in do/end_do loop: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression if there is one */
if (open_parens != NULL) {
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
}
/* construct and dump the jump to the end_do label */
if (open_parens != NULL) {
strcpy( out_buff, " if " ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, " goto " ) ;
strcat( out_buff, dlabel[do_count] ) ;
free( exp ) ;
}
else {
strcpy( out_buff, " goto " ) ;
strcat( out_buff, dlabel[do_count] ) ;
}
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function CONTINUE_PROC
*
* Process continue statements (part of begin construct).
*
* P. R. OVE 10/10/86
*/
continue_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if there is stuff on the line (open_parens != NULL) and no open
* parens (close_parens == NULL) assume variable name like CONTINUEit */
if ( (open_parens != NULL) & (close_parens == NULL) ) return ;
/* on missing begin statement, abort */
if ( begin_count <= 0 ) {
sprintf( errline, "CONTINUE: no matching BEGIN: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression if there is one */
if (open_parens != NULL) {
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
}
/* construct and dump the back to the begin statement */
if (open_parens != NULL) {
strcpy( out_buff, " if " ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, " goto " ) ;
strcat( out_buff, blabel[begin_count] ) ;
free( exp ) ;
}
else {
strcpy( out_buff, " goto " ) ;
strcat( out_buff, blabel[begin_count] ) ;
}
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function DEFAULT_PROC
*
* Process default statements.
*
* P. R. OVE 11/9/85
*/
default_proc()
{
char *pntr ;
if ( case_count <= 0 ) {
sprintf( errline, "DEFAULT: no matching CASE: %s", in_buff ) ;
abort( errline ) ;
}
dump( " else" ) ;
/* eliminate "default" from the input buffer */
pntr = line_end( first_nonblank + name_length ) ;
if ( pntr != NULL ) {
strcpy( in_buff, "\t" ) ;
strcat( in_buff, pntr ) ;
}
else { IN_BUFF_DONE }
}
/* Function DO_PROC
*
* Process do statements. If there is a label (ala
* fortran) just dump it to the output. If no label
* exists make one up in anticipation of an eventual
* end_do statement.
*
* P. R. OVE 11/9/85
*/
do_proc()
{
char *after_do, *pntr ;
int count ;
/* return without processing if the first nonblank char after DO is a label
or if there is no blank/tab after the DO */
pntr = first_nonblank + name_length ;
after_do = line_end( pntr ) ;
if ( ( strchr( "0123456789", *after_do ) != NULL ) |
( after_do == pntr ) ) return ;
/* keep track of the nesting */
do_count++ ;
if ( do_count >= NESTING ) {
sprintf( errline, "DO: nesting too deep: %s", in_buff ) ;
abort( errline ) ;
}
/* make up a label and store it in dlabel[do_count] */
count = 12500 + dlabel_count ;
dlabel_count++ ;
if ( count > 14999 ) {
sprintf( errline, "DO: too many labels: %s", in_buff ) ;
abort( errline ) ;
}
sprintf( dlabel[do_count], "%d", count ) ;
/* make label for leave_do to jump to and store it in elabel[do_count] */
count = 22500 + elabel_count ;
elabel_count++ ;
if ( count > 24999 ) {
sprintf( errline, "DO: too many labels: %s", in_buff ) ;
abort( errline ) ;
}
sprintf( elabel[do_count], "%d", count ) ;
/* construct and dump the output record */
sprintf( out_buff, " do %s %s", dlabel[do_count], after_do ) ;
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function END_CASE_PROC
*
* Process end_case statements.
*
* P. R. OVE 11/9/85
*/
end_case_proc()
{
of_count[ case_count ] = 0 ;
free( case_exp[ case_count ] ) ;
case_count-- ;
IN_BUFF_DONE
if ( case_count < 0 ) {
case_count = 0 ;
return ; }
dump( " end if" ) ;
}
/* Function END_DO_PROC
*
* Process end_do statements. Use the label indexed
* by the current value of do_count (the do nesting
* index).
*
* P. R. OVE 11/9/85
*/
end_do_proc()
{
/* signal error if no matching do has been found */
if ( do_count <= 0 ) {
sprintf( errline, "END_DO: no matching do: %s", in_buff ) ;
abort( errline ) ;
}
/* construct and dump the normal do loop continue statement */
sprintf( out_buff, "%s continue", dlabel[do_count] ) ;
dump( out_buff ) ;
/* construct and dump the leave_do label if needed */
if ( leave_do_flag[do_count] == TRUE ) {
sprintf( out_buff, "%s continue", elabel[do_count] ) ;
dump( out_buff ) ;
leave_do_flag[do_count] = FALSE ;
}
do_count -= 1 ;
IN_BUFF_DONE
}
/* Function LEAVE_DO_PROC
*
* Process leave_do statements.
*
* P. R. OVE 3/2/86
*/
leave_do_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if there is stuff on the line (open_parens != NULL) and no */
/* open parens (close_parens == NULL) assume variable name like LEAVE_DOit */
if ( (open_parens != NULL) & (close_parens == NULL) ) return ;
/* on missing do statement, abort */
if ( do_count <= 0 ) {
sprintf( errline, "LEAVE_DO: not in do/end_do loop: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression if there is one */
if (open_parens != NULL) {
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
}
/* construct and dump the jump out of the loop */
if (open_parens != NULL) {
strcpy( out_buff, " if " ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, " goto " ) ;
strcat( out_buff, elabel[do_count] ) ;
free( exp ) ;
}
else {
strcpy( out_buff, " goto " ) ;
strcat( out_buff, elabel[do_count] ) ;
}
leave_do_flag[do_count] = TRUE ;
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function LEAVE_PROC
*
* Process leave statements.
*
* P. R. OVE 3/2/86
*/
leave_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if there is stuff on the line (open_parens != NULL) and no */
/* open parens (close_parens == NULL) assume variable name like LEAVEit */
if ( (open_parens != NULL) & (close_parens == NULL) ) return ;
/* on missing begin statement, abort */
if ( begin_count <= 0 ) {
sprintf( errline, "LEAVE: no matching begin: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression if there is one */
if (open_parens != NULL) {
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
}
/* construct and dump the jump to again */
if (open_parens != NULL) {
strcpy( out_buff, " if " ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, " goto " ) ;
strcat( out_buff, alabel[begin_count] ) ;
free( exp ) ;
}
else {
strcpy( out_buff, " goto " ) ;
strcat( out_buff, alabel[begin_count] ) ;
}
dump( out_buff ) ;
IN_BUFF_DONE
}
/* Function OF_PROC
*
* Process of statements.
*
* P. R. OVE 11/9/85
*/
of_proc()
{
int n ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length) ;
close_parens = mat_del( open_parens ) ;
/* if no open parens assume variable name like OFile */
/* (no open parens <==> close_parens will be NULL) */
if ( close_parens == NULL ) return ;
/* abort on missing case statement */
if ( case_count <= 0 ) {
sprintf( errline, "OF: missing CASE statement: %s", in_buff ) ;
abort( errline ) ;
}
/* keep track of "of's" for each case level */
of_count[ case_count ] += 1 ;
/* get the logical expression */
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
/* construct the "if" or "if else" statement. If there is a case */
/* logical expression us .eq. to determine the result */
if ( case_exp[ case_count ][0] == NULL ) {
if ( of_count[ case_count ] != 1 ) {
strcpy( out_buff, " else if " ) ; }
else {
strcpy( out_buff, " if " ) ; }
strcat( out_buff, exp ) ;
strcat( out_buff, " then " ) ; }
else {
if ( of_count[ case_count ] != 1 ) {
strcpy( out_buff, " else if (" ) ; }
else {
strcpy( out_buff, " if (" ) ; }
strcat( out_buff, case_exp[ case_count ] ) ;
strcat( out_buff, ".eq." ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, ") then " ) ; }
dump( out_buff ) ;
/* eliminate "of stuff" from the input buffer */
pntr = line_end( close_parens + 1 ) ;
if ( pntr != NULL ) {
strcpy( in_buff, "\t" ) ;
strcat( in_buff, pntr ) ;
}
else { IN_BUFF_DONE }
free( exp ) ;
}
/* Function UNTIL_PROC
*
* Process until statements.
*
* P. R. OVE 3/2/86
*/
until_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if no open parens assume variable name like UNTILon */
/* (no open parens <==> close_parens will be NULL) */
if ( close_parens == NULL ) return ;
/* on missing begin statement, abort */
if ( begin_count <= 0 ) {
sprintf( errline, "UNTIL: no matching begin: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression */
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
/* construct and dump the conditional jump to begin */
sprintf( out_buff, " if (.not.%s) goto %s",
exp, blabel[begin_count] ) ;
dump( out_buff ) ;
/* construct a label statement (for leave to jump to) */
sprintf( out_buff, "%s continue", alabel[begin_count] ) ;
dump( out_buff ) ;
begin_count-- ;
free( exp ) ;
IN_BUFF_DONE
}
/* Function WHILE_PROC
*
* Process while statements.
*
* P. R. OVE 3/2/86
*/
while_proc()
{
int n, count ;
char *pntr, *open_parens, *close_parens ;
/* get the comparison expression */
open_parens = line_end( first_nonblank + name_length ) ;
close_parens = mat_del( open_parens ) ;
/* if no open parens assume variable name like WHILEon */
/* (no open parens <==> close_parens will be NULL) */
if ( close_parens == NULL ) return ;
/* on missing begin statement, abort */
if ( begin_count <= 0 ) {
sprintf( errline, "WHILE: no matching begin: %s", in_buff ) ;
abort( errline ) ;
}
/* get the logical expression */
n = close_parens - open_parens - 1 ;
GET_MEM( exp, n+5 ) ;
exp[0] = '(' ;
strncpy( exp + 1, open_parens + 1, n ) ;
exp[n+1] = ')' ;
exp[n+2] = NULL ;
/* construct and dump the output record */
strcpy( out_buff, " if (.not." ) ;
strcat( out_buff, exp ) ;
strcat( out_buff, ") goto " ) ;
strcat( out_buff, alabel[begin_count] ) ;
dump( out_buff ) ;
free( exp ) ;
IN_BUFF_DONE
}
@//E*O*F flow.c//
chmod u=rw,g=r,o=r flow.c
echo x - misc.c
sed 's/^@//' > "misc.c" <<'@//E*O*F misc.c//'
/* misc routines */
#include "prep.h"
/* Function DUMP.C
*
* Send a string to the output stream. The string is a
* fortran record constructed by PREP, which may be
* longer than 72 characters after processing. It is
* broken up into pieces before output. The string
* must be null terminated. The string is not affected
* by this routine, so it is safe to do
* dump( "explicit text" ) ;
*
* If inside a vector loop (vec_flag==TRUE) the record is
* not broken up and is sent to mem_store rather than a file.
*
* P. R. OVE 11/9/85
*/
dump( string )
char *string ;
{
char record[73], *pntr ;
int i_str, i_rec = 0, i, i_tab, quote_flag = 0 ;
/* ignore empty lines sent here */
if ( NULL == line_end( string ) ) return ;
/* if in a vector loop write the string to mem_store */
if ( vec_flag ) {
push( string ) ;
return ;
}
/* loop until end of record */
for ( i_str = 0;; i_str++ ) {
/* wrap up on end of line */
if ( line_end( &string[i_str] ) == NULL ) {
record[i_rec] = NULL ;
put_string( record ) ;
break ; }
/* break string if necessary */
if ( i_rec >= 72 ) {
record[i_rec] = NULL ;
put_string( record ) ;
strcpy( record, " *" ) ;
i_str-- ;
i_rec = 6 ;
continue ;
}
/* toggle quote flag on quotes */
if ( string[i_str] == '\'' ) quote_flag = ! quote_flag ;
/* underline filtering */
if ( (string[i_str]=='_') & (!underline_keep) & (!quote_flag) )
continue ;
/* tab handling */
if ( string[i_str] == TAB ) {
if ( i_rec >= 70 - tab_size ) {
record[i_rec] = NULL ;
put_string( record ) ;
strcpy( record, " *" ) ;
i_rec = 6 ; }
else { /* replace tab by blanks */
i_tab = ( ( i_rec + 1 )/tab_size )
* tab_size - i_rec + tab_size - 1 ;
for ( i = 0; i < i_tab; i++ ) {
record[i_rec] = BLANK ;
i_rec++ ; }
}
continue ;
}
/* default action */
record[i_rec] = string[i_str] ;
i_rec++ ;
}
}
/* GET_RECORD
*
* Get a record from the input stream, making sure that the buffer
* does not overflow by increasing its size as necessary. The
* string in_buff will contain the record on return. In_buff will
* always contain about ten percent of its default length in trailing
* blanks to play with. Out_buff will have space allocated for it
* as well, 4 times that of in_buff. Returns a pointer to the
* terminating NULL character. On EOF the previous input file
* (assuming the present one was an include file) will be restored as
* the input file. If the filestack is empty return NULL.
*/
char *get_rec()
{
int i, j ;
char *pntr, *area ;
/* fill the in_put buffer, enlarging it when nearly full in
* increments of DEF_BUFFSIZE. On end of file the previous file
* handle is popped from the include stack (if present).
*/
pntr = in_buff ;
i = 0 ;
while(1) {
for (; i < allocation - DEF_BUFFSIZE/10 ; i++, pntr++ ) {
*pntr = getc(in) ;
if ( *pntr == EOF ) {
fclose(in) ;
if ( NULL == popfile(&in) ) return( NULL ) ;
pntr = in_buff-1 ;
i = -1 ;
continue ;
}
if ( *pntr == '\n' ) {
*pntr = NULL ;
return( pntr ) ;
}
}
/* if control falls through to here, increase buffer sizes. */
allocation += DEF_BUFFSIZE ;
if ( NULL == realloc( in_buff, allocation ) )
abort( "Reallocation failed" ) ;
if ( NULL == realloc( out_buff, 4*allocation ) )
abort( "Reallocation failed" ) ;
}
}
/* Include_proc
*
* Handle file inclusion
*
* P. R. OVE 11/9/85
*/
include_proc()
{
char *pntr, *open_parens, *close_parens, *name ;
/* get the file name */
open_parens = line_end( first_nonblank + name_length ) ;
if ( NULL == ( close_parens = mat_del( open_parens ) ) ) {
sprintf( errline, "INCLUDE: syntax: %s", in_buff ) ;
abort( errline ) ;
}
name = open_parens+1 ;
*close_parens = NULL ;
/* push the old input file handle onto the filestack */
if ( NULL == pushfile(&in) ) {
sprintf( errline, "INCLUDE: nesting too deep: %s", in_buff ) ;
abort( errline ) ;
}
/* open the new file */
if ( NULL == ( in = fopen( name, "r" ) ) ) {
sprintf( errline, "INCLUDE: can't open file: %s", name ) ;
abort( errline ) ;
}
IN_BUFF_DONE ;
}
/* push a file handle onto the filestack. return NULL on error. */
int pushfile(handleaddress)
FILE *(*handleaddress) ;
{
if ( include_count >= NESTING ) return(NULL) ;
filestack[include_count] = *handleaddress ;
include_count++ ;
return(1) ;
}
/* pop a file handle from the filestack. return NULL on error */
int popfile(handleaddress)
FILE *(*handleaddress) ;
{
if ( include_count <= 0 ) return(NULL) ;
include_count-- ;
*handleaddress = filestack[include_count] ;
return(1) ;
}
/* Function LINE_END
*
* Return a NULL pointer if the string contains only
* blanks and tabs or if it is a NULL string. Else
* return a pointer to the first offending character.
*
* P. R. OVE 11/9/85
*/
char *line_end( string )
char *string ;
{
for (; *string != NULL; string++ )
if ( (*string != BLANK) && (*string != TAB) ) return(string) ;
return( NULL ) ;
}
/* Function MAT_DEL
*
* Given pointer to a delimeter this routine finds its
* partner and returns a pointer to it. On failure a
* NULL pointer is returned. The supported delimeters
* are:
*
* ' " ( ) [ ] { } < >
*
* ' and " are supported only in the forward direction
* and no nesting is detected.
* In all cases the search is limited to the current
* line (bounded by NULLs).
*
* P. R. OVE 11/9/85
*/
char *mat_del( pntr )
char *pntr ;
{
int nest_count = 0, i, direction ;
char target ;
if ( pntr == NULL ) return( NULL ) ;
/* get the target character and direction of search */
switch( *pntr ) {
case '(' : { target = ')' ;
direction = 1 ;
break ; }
case ')' : { target = '(' ;
direction = -1 ;
break ; }
case '[' : { target = ']' ;
direction = 1 ;
break ; }
case ']' : { target = '[' ;
direction = -1 ;
break ; }
case '{' : { target = '}' ;
direction = 1 ;
break ; }
case '}' : { target = '{' ;
direction = -1 ;
break ; }
case '<' : { target = '>' ;
direction = 1 ;
break ; }
case '>' : { target = '<' ;
direction = -1 ;
break ; }
case '\'': { target = '\'' ;
direction = 1 ;
break ; }
case '\"': { target = '\"' ;
direction = 1 ;
break ; }
default: return( NULL ) ;
}
/* find the match */
for ( i = direction; pntr[i] != NULL; i += direction ) {
if ( pntr[i] == target ) {
if ( nest_count == 0 ) {
break ; }
else {
nest_count-- ;
continue ; }
}
if ( pntr[i] == pntr[0] ) nest_count++ ;
}
if ( &pntr[i] == NULL ) return( NULL ) ;
return( &pntr[i] ) ;
}
/* PARMER
*
* Processes the command line parameters.
*/
int parmer ( argc, argv )
int argc ;
char *argv[] ;
{
int i ;
/* default io streams */
in = stdin ;
out = stdout ;
/* use in_buff to hold file inclusion command if found */
IN_BUFF_DONE ; /* clear the buffer */
for ( i = 1; i < argc; i++ ) {
/* assume data file name if not a switch */
if ( argv[i][0] != '-' ) {
sprintf( dataf, "%s.p", argv[i] ) ;
if ( NULL != ( in = fopen( dataf, "r" ) ) ) {
sprintf( dataf, "%s.f", argv[i] ) ;
out = fopen( dataf, "w" ) ;
}
else in = stdin ;
}
else {
/* switches */
switch ( argv[i][1] ) {
case 'c' : com_keep = TRUE ; break ;
case 'u' : underline_keep = TRUE ; break ;
case 'U' : i++ ;
if ( i < argc ) {
if ( argv[i][0] == '-' ||
NULL==sscanf(argv[i],"%d",&unroll_depth) ){
unroll_depth = DEF_UNROLL_DEPTH ;
i-- ;
break ;
}}
else unroll_depth = DEF_UNROLL_DEPTH ;
break ;
case 'L' : i++ ;
if ( i < argc ) {
if ( argv[i][0] == '-' ||
NULL==sscanf(argv[i],"%d",&line_limit) ){
line_limit = DEF_LINE_LIMIT ;
i-- ;
break;
}}
else line_limit = DEF_LINE_LIMIT ;
break ;
case 'm' : macro_only = TRUE ;
underline_keep = TRUE ;
com_keep = TRUE ;
break ;
case 'i' : i++ ;
if ( i < argc ) {
sprintf(in_buff,"#include \"%s\"", argv[i] ) ;
break ;
}
default : fprintf( stderr, "\nUnrecognized switch: %s\n", argv[i]);
fprintf( stderr, "\nAllowed switches:\n\n%s\n%s\n%s\n%s\n%s\n%s",
" -c keep comments",
" -u keep underline characters",
" -m expand macros only",
" -i <file> include <file> before processing",
" -U n unroll vector loops to depth n",
" -L n unroll loops with n or fewer lines only"
) ;
abort( "\n" ) ;
}
}
}
/* process the file include statement if present */
if ( IN_BUFF_FULL ) preproc( rec_type(0) ) ;
return(1) ;
}
/* Function PREPROCESS.C
*
* The guts of the preprocessor PREP. Variable tipe
* contains the type of record code:
*
* BEGIN statement
* AGAIN statement
* WHILE statement
* UNTIL statement
* CONTINUE statement
* LEAVE statement
*
* CASE statement
* OF statement
* DEFAULT statement
* CONTINUE_CASE statement
* END_CASE statement
* DO_LIMITS statement
* UNROLL statement
*
* DO statement
* LEAVE_DO statement
* CONTINUE_DO statement
* END_DO statement
*
* [ (start of clustered vector arithmetic)
* ] ( end " " " " )
* # vectored arithmetic statement
* normal (normal fortran statement)
*
* INCLUDE files
* MACRO expansion
*
* P. R. OVE 11/9/85
*/
preproc(tipe)
int tipe ;
{
switch ( tipe ) {
case unknown : break ;
case normal : strcpy( out_buff, in_buff ) ;
dump( out_buff ) ;
in_buff[0] = NULL ;
break ;
case type_begin : begin_proc() ; break ;
case type_again : again_proc() ; break ;
case type_while : while_proc() ; break ;
case type_until : until_proc() ; break ;
case type_continue : continue_proc() ; break ;
case type_leave : leave_proc() ; break ;
case type_case : case_proc() ; break ;
case type_of : of_proc() ; break ;
case type_default : default_proc() ; break ;
case type_continue_case:continue_case_proc() ; break ;
case type_end_case : end_case_proc() ; break ;
case type_do_limits : do_limits_proc() ; break ;
case type_unroll : unroll_proc() ; break ;
case type_do : do_proc() ; break ;
case type_end_do : end_do_proc() ; break ;
case type_leave_do : leave_do_proc() ; break ;
case type_continue_do : continue_do_proc() ; break ;
case type_osqb : osqb_proc() ; break ;
case type_vec : vec_proc() ; break ;
case type_csqb : csqb_proc() ; break ;
case type_include : include_proc() ; break ;
}
}
/* PUSH
*
* Push a string onto the MEM_STORE. Space is allocated for it and
* a pointer kept in the array mem_store (array of pointers). The
* index to mem_store at which the current string is stored is returned.
* If the input string is a NULL pointer the last entry is removed.
* Global variable mem_count keeps track of the total number of pointers
* in use.
*/
int push( string )
char *string ;
{
int i ;
if ( string != NULL ) {
if ( mem_count >= STORE_SIZE - 1 ) {
sprintf( errline, "PUSH out of memory pointers: %s", in_buff ) ;
abort( errline ) ;
}
GET_MEM( mem_store[ mem_count ], strlen( string ) ) ;
strcpy( mem_store[ mem_count ], string ) ;
mem_count++ ;
return( mem_count - 1 ) ;
}
if ( mem_count > 0 ) {
mem_count-- ;
free( mem_store[ mem_count ] ) ;
return( mem_count - 1 ) ;
}
}
/* Function REC_TYPE.C
*
* Determine the type of a record.
*
* P. R. OVE 11/9/85
*/
char *strchrq() ;
int rec_type( group )
int group ;
{
char combuff[16], *string ;
int i ;
if (in_buff[0] == NULL) return(unknown) ;
string = in_buff ;
/* go to first nonblank character, save a pointer to it */
while ( *string != NULL ) {
if ( *string != TAB & *string != BLANK ) {
first_nonblank = string ;
break ;
}
string++ ;
}
/* copy the initial characters into combuff */
for ( i = 0; (i < 15) & (*string != NULL); i++ ) {
combuff[i] = string[i] ;
}
combuff[15] = NULL ;
strupr( combuff ) ; /* convert to upper case */
/* check for commands by group */
switch ( group ) {
/* group 0 commands: file includes */
case 0 : {
if ( MATCH( "#INCLUDE" ) ) return(type_include) ;
return(unknown) ;
}
/* group 1 commands: case's OF and DEFAULT commands are done first so
that it is legal to have: of ( 'a' ) leave_do, for instance.
*/
case 1 : {
if ( MATCH( "OF" ) ) return(type_of) ;
if ( MATCH( "DEFAULT" ) ) return(type_default) ;
return(unknown) ;
}
/* group 2 commands: flow control extensions and parameter changes */
case 2 : {
if ( MATCH( "DO_LIMITS" ) ) return(type_do_limits) ;
if ( MATCH( "DO LIMITS" ) ) return(type_do_limits) ;
if ( MATCH( "DO" ) ) return(type_do) ;
if ( MATCH( "END_DO" ) ) return(type_end_do) ;
if ( MATCH( "END DO" ) ) return(type_end_do) ;
if ( MATCH( "LEAVE_DO" ) ) return(type_leave_do) ;
if ( MATCH( "LEAVE DO" ) ) return(type_leave_do) ;
if ( MATCH( "CONTINUE_DO")) return(type_continue_do) ;
if ( MATCH( "CONTINUE DO")) return(type_continue_do) ;
if ( MATCH( "CASE" ) ) return(type_case) ;
if ( MATCH( "END_CASE" ) ) return(type_end_case) ;
if ( MATCH( "END CASE" ) ) return(type_end_case) ;
if (MATCH("CONTINUE_CASE")) return(type_continue_case) ;
if (MATCH("CONTINUE CASE")) return(type_continue_case) ;
if ( MATCH( "BEGIN" ) ) return(type_begin) ;
if ( MATCH( "AGAIN" ) ) return(type_again) ;
if ( MATCH( "WHILE" ) ) return(type_while) ;
if ( MATCH( "UNTIL" ) ) return(type_until) ;
if ( MATCH( "LEAVE" ) ) return(type_leave) ;
if ( MATCH( "CONTINUE" ) ) return(type_continue) ;
if ( MATCH( "UNROLL" ) ) return(type_unroll) ;
return(unknown) ;
}
/* group 3 commands: vector processing */
case 3: {
if ( MATCH( "[" ) ) return(type_osqb) ;
if ( strchrq( string, ']' ) != NULL ) return(type_csqb) ;
if ( strchrq( string, '#' ) != NULL ) return(type_vec) ;
return(normal) ;
}
} /* end switch case */
}
/* Look for unquoted character in string, where ' is the fortran quote char.
* Returns a pointer to the character, or a NULL pointer if not present.
*/
char *strchrq( string, c )
char *string, c ;
{
int i, quote=1 ;
for ( i = 0; string[i] != NULL; i++ ) {
if ( string[i] == '\'' ) {
quote = -quote ;
continue ;
}
if ( string[i] == c && quote == 1 ) return( &string[i] ) ;
}
return( NULL ) ; /* not found */
}
/* strmatch: find the first occurrence of string2 in string1, return pointer
* to the first character of the match. Returns NULL pointer if no match.
*/
#define NULL 0
char *strmatch( string1, string2 )
char *string1, *string2 ;
{
char *pntr1, *pntr2 ;
for ( pntr1 = string1, pntr2 = string2 ; *pntr1 != NULL; pntr1++ ) {
if ( *pntr1 == *pntr2 ) {
pntr2++ ;
if ( *pntr2 == NULL ) return( pntr1 - strlen(string2) + 1 ) ;
}
else pntr2 = string2 ;
}
/* failure if control reaches this point */
return( NULL ) ;
}
/* function STRTOKP
Like Strtok, except that the original string is preserved (strtok
puts null in there to terminate the substrings). This routine
uses mallocs to allow storage for the token. The memory is
reallocated for each new string. Use just like strtok:
Successively returns the tokens in string1, using the delimeters
defined by string2. If string1 is NULL (a NULL pointer) the
routine returns the next token in the string from the previous call.
Otherwise the first token is returned. A NULL pointer is returned
on failure (no more tokens in the current string).
*/
char *strtokp( string1, string2 )
char *string1, *string2 ;
{
static char *spntr, *tpntr, *token ;
static int called = NULL ; /* called=NULL ==> initialize */
int i ;
/* initialize on first call */
if ( called == NULL ) {
called = 1 ;
GET_MEM( token, strlen(string1) ) ;
}
/* if string1 is not NULL reset the routine */
if ( string1 != NULL ) {
spntr = string1 ;
if ( NULL == ( token = realloc( token, strlen(string1)+1 )))
abort("STRTOKP: reallocation error") ;
}
if ( *spntr == NULL ) return( NULL ) ; /* end of original string */
/* skip initial delimeter characters */
for (; NULL != strchr( string2, *spntr ); spntr++ ) ;
/* copy characters to token until the next delimeter */
tpntr = &token[0] ;
for (; *spntr != NULL; spntr++ ) {
if ( NULL != strchr( string2, *spntr ) ) break ;
*tpntr = *spntr ;
tpntr++ ;
}
*tpntr = NULL ;
/* return result to caller */
if ( token[0] == NULL ) return( NULL ) ;
return( &token[0] ) ;
}
/* strupr: convert a string to upper case.
*/
char *strupr( string )
char *string ;
{
int i ;
for ( i=0; i<strlen( string ); i++ )
if ( string[i] > 96 & string[i] < 123 ) string[i] -= 32 ;
return( string ) ;
}
/* Tokenize
*
* Break out arguments from a string. Pntr is the argument string
* and tokens is an array of pointers which will be assigned memory and have
* the arguments returned. The function returns the number of arguments
* found. Pairwise characters are monitored to ensure that expressions
* are sexually balanced. Unused parm pointers are returned NULL.
* MAX_TOKENS determines the dimension of the array of pointers.
* Commas are the only delimiters allowed to distinquish tokens.
*/
int tokenize( pntr, tokens )
char *pntr, *tokens[] ;
{
int square = 0, curl = 0, parens = 0, apost = 1, quote = 1 ;
int i, j, quit ;
char *text, *txt ;
/* clear the pointers and make a copy of the string */
for ( i=0; i<MAX_TOKENS; i++ ) tokens[i] = NULL ;
GET_MEM( text, strlen(pntr) ) ;
strcpy( text, pntr ) ;
for ( i=0, j=0, quit=FALSE, txt=text; quit==FALSE; j++ ) {
switch( text[j] ) {
case '[' : square += 1 ; break ;
case ']' : square -= 1 ; break ;
case '{' : curl += 1 ; break ;
case '}' : curl -= 1 ; break ;
case '(' : parens += 1 ; break ;
case ')' : parens -= 1 ; break ;
case '\'' : apost = -apost; break ;
case '\"' : quote = -quote; break ;
case NULL :
GET_MEM( tokens[i], strlen(txt) ) ;
strcpy( tokens[i], txt ) ;
quit = TRUE ;
break ;
case ',' : if (!square && !curl && !parens &&(apost==1)&&(quote==1)){
text[j] = NULL ;
GET_MEM( tokens[i], strlen(txt) ) ;
strcpy( tokens[i], txt ) ;
i += 1 ;
txt = &text[j+1] ;
}
}
}
free( text ) ;
return( i+1 ) ;
}
@//E*O*F misc.c//
chmod u=rw,g=r,o=r misc.c
echo x - fix.h
sed 's/^@//' > "fix.h" <<'@//E*O*F fix.h//'
: .eq. ==; file for imbedding a few macros in a fortran program
: .ge. >=;
: .gt. >; to use do: prep -m -i fix.h <file >output
: .lt. <;
: .le. <=;
: .ne. !=;
: ** ^;
: .and. &;
: .or. |;
: .not. !;
: .true. TRUE;
: .false. FALSE;
@//E*O*F fix.h//
chmod u=rw,g=r,o=r fix.h
echo x - macro.h
sed 's/^@//' > "macro.h" <<'@//E*O*F macro.h//'
/* macro related stuff */
#include "prep.h"
#define MAX_MACROS 1000
#define MAX_CALLS 100 /* if exceeded, assume recursive */
/* macro structure */
struct mac {
char *name ;
char *text ;
int parmcount ;
int callcount ;
} macro[MAX_MACROS], *macrop ;
int defined_macros = 0 ; /* number of defined macros */
/* function types */
char *expand_macros(), *mac_expand(), *strmatch() ;
int define_macro() ;
@//E*O*F macro.h//
chmod u=rw,g=r,o=r macro.h
echo x - prep.h
sed 's/^@//' > "prep.h" <<'@//E*O*F prep.h//'
#ifdef MAIN
/*
Included stuff for main routine of program PREP
*/
#include "stdio.h"
#include "string.h"
#include "prepdf.h"
/* global pointers & storage */
char *in_buff, *out_buff ; /* text buffer pointers */
char *phys_ibuff ; /* physical input buffer */
char *phys_obuff ; /* physical output buffer */
char *mem_store[STORE_SIZE] ; /* pointers to malloc areas */
char *initial_name[NESTING] ; /* do loop initial values */
char *limit_name[NESTING] ; /* do loop limits */
char *increment_name[NESTING] ; /* do loop increments */
char *case_exp[NESTING] ; /* case expression storage */
char *exp ; /* general expression storage pointer */
char *first_nonblank ; /* first nb char in in_buff */
char label[NESTING][6] ; /* label storage (vector loops) */
char alabel[NESTING][6] ; /* again label storage */
char blabel[NESTING][6] ; /* begin label storage */
char clabel[NESTING][6] ; /* case label storage */
char dlabel[NESTING][6] ; /* do/end_do label storage */
char elabel[NESTING][6] ; /* leave_do label storage */
char var_name[NESTING][6] ; /* do counter names */
char dataf[DEF_BUFFSIZE] ; /* data file name */
char errline[2*DEF_BUFFSIZE] ; /* error message line */
long allocation ; /* current size of in_buff */
int of_count[NESTING] ; /* counters for of statements */
int leave_do_flag[NESTING] ; /* marks if leave_do in current loop */
int var_count = 0 ; /* number of variables used in do loops */
int label_count = 0 ; /* label = label_count + 10000 */
int alabel_count = 0 ; /* alabel = alabel_count + 15000 */
int blabel_count = 0 ; /* blabel = blabel_count + 17500 */
int clabel_count = 0 ; /* clabel = clabel_count + 20000 */
int dlabel_count = 0 ; /* dlabel = dlabel_count + 12500 */
int elabel_count = 0 ; /* elabel = elabel_count + 22500 */
int do_count = 0 ; /* nesting counter for do/end_do */
int begin_count = 0 ; /* nesting counter for begin ... loops */
int case_count = 0 ; /* case nesting level */
int tab_size = 7 ; /* size of the tab in blanks */
int unroll_depth = 0 ; /* do loop unroll depth, 0 for no unrolling */
int line_limit = 1000 ; /* unroll loops if # lines <= line_limit */
int mem_count = 0 ; /* mem_store external counter */
int include_count = 0 ; /* index of filestack (for includes) */
int name_length = 0 ; /* current command name length */
int vec_flag = FALSE ; /* TRUE if in vector loop */
int com_keep = FALSE ; /* TRUE to keep comments */
int underline_keep=FALSE; /* TRUE to keep underline characters */
int macro_only = FALSE ; /* TRUE to do only macro expansion */
FILE *in, *out, *filestack[NESTING] ;
/* function declarations */
char *get_rec(), *mac_proc(), *malloc(), *realloc() ;
#else
/* Header file for the functions of program PREP */
#include "stdio.h"
#include "string.h"
#include "prepdf.h"
/* global pointers & storage */
extern char *in_buff, *out_buff, *phys_ibuff, *phys_obuff,
*mem_store[],
*initial_name[], *limit_name[], *increment_name[],
*case_exp[], *exp, *first_nonblank,
label[][6],
alabel[][6], blabel[][6], clabel[][6], dlabel[][6], elabel[][6],
var_name[][6],
dataf[], errline[] ;
extern int var_count, tab_size, unroll_depth, line_limit,
com_keep, vec_flag, label_count,
alabel_count, blabel_count, clabel_count,
dlabel_count, elabel_count,
case_count, of_count[], do_count, begin_count,
mem_count, underline_keep, include_count, macro_only,
name_length, leave_do_flag[] ;
extern long allocation ;
extern FILE *in, *out, *filestack[] ;
/* function type declarations */
char *mat_del(), *line_end(), *get_rec(), get_a_char(),
*malloc(), *calloc(), *realloc(), *strtokp(),
*mac_proc(), *strupr() ;
#endif
@//E*O*F prep.h//
chmod u=rw,g=r,o=r prep.h
echo x - prepdf.h
sed 's/^@//' > "prepdf.h" <<'@//E*O*F prepdf.h//'
/* #define CRAY 1 */
#define BLANK ' '
#define TAB '\t'
#define TRUE 1
#define FALSE 0
#define NOT !
#define DEF_UNROLL_DEPTH 8
#define DEF_LINE_LIMIT 1
#define DEF_BUFFSIZE 200
#define PHYS_IBUFF_SIZE 10000
#define PHYS_OBUFF_SIZE 0 /* not used, uses sys output buffer */
#define STORE_SIZE 1000
#define NESTING 10
#define MAX_TOKENS 2*NESTING /* tokens and macro args */
#define exp expression /* used exp as a variable */
#define IN_BUFF_DONE in_buff[0] = NULL ;
#define IN_BUFF_FULL line_end( in_buff ) != NULL
#define UNROLLING ( ( unroll_depth > 1 ) && \
( mem_count <= line_limit ) && \
( var_count > 1 ) )
#define GET_MEM(S,A)\
if ( NULL == (S = malloc(A+1)) ) {\
abort( "Memory allocation failed") ; }
#define MATCH(S) ( strncmp( combuff, S, (name_length=strlen(S)) ) == 0 )
#define put_string(s) fputs( s, out ) ; putc( '\n', out ) ;
/* enumeration of command types, by hand because of svs c enum bug */
#define type_begin 0
#define type_again 1
#define type_while 2
#define type_until 3
#define type_leave 4
#define type_case 5
#define type_of 6
#define type_default 7
#define type_end_case 8
#define type_do_limits 9
#define type_do 10
#define type_end_do 11
#define type_osqb 12
#define type_csqb 13
#define type_vec 14
#define type_unroll 15
#define type_continue 16
#define type_leave_do 17
#define type_continue_do 18
#define type_continue_case 19
#define normal 20
#define type_include 21
#define unknown 22
#ifdef CRAY
/* the cray considers characters to be unsigned */
#undef EOF
#define EOF 255
/* a few macros to adapt to cray namelength limitations */
#define continue_proc cont_proc
#define continue_do_proc cont_do_proc
#define leave_do_proc le_do_proc
#define include_proc inc_proc
#endif
@//E*O*F prepdf.h//
chmod u=rw,g=r,o=r prepdf.h
echo x - prepmac.h
sed 's/^@//' > "prepmac.h" <<'@//E*O*F prepmac.h//'
c Some standard macros for prep.
c logical stuff
: == .eq. ;
: >= .ge. ;
: > .gt. ;
: < .lt. ;
: <= .le. ;
: != .ne. ;
: <> .ne. ;
: ! .not. ;
: | .or. ;
: & .and. ;
: TRUE .true. ;
: FALSE .false. ;
: ^ ** ;
c flow control redefinitions
: enddo end_do ;
: ->begin continue ;
: ->case continue_case ;
: ->do continue_do ;
@//E*O*F prepmac.h//
chmod u=rw,g=r,o=r prepmac.h
echo x - string.h
sed 's/^@//' > "string.h" <<'@//E*O*F string.h//'
/* @(#)strings.h 1.1 85/12/18 SMI; from UCB 4.1 83/05/26 */
/*
* External function definitions
* for routines described in string(3).
*/
char *strcat();
char *strncat();
int strcmp();
int strncmp();
char *strcpy();
char *strncpy();
int strlen();
char *index();
char *rindex();
char *strchr();
int strspn();
int strcspn();
@//E*O*F string.h//
chmod u=rw,g=r,o=r string.h
echo x - vecdem.h
sed 's/^@//' > "vecdem.h" <<'@//E*O*F vecdem.h//'
c macros defs for vec demo
#include "prepmac.h"
: XLIM 81 ; hard dimensions of arrays are from 0 --> ?lim
: YLIM 81 ;
: SCRNX 320 ; geodesic drawing screen dimensions
: SCRNY 200 ;
: PHOTONS 64 ; number of photons
: SMALL 1.e-20 ;
: BIG 1.e+20 ;
: include(x) use x ; cray specific file include
: PERIODIC(x) call periodic( mx, my, x ) ;
c default do limits
do_limits = [ (XLIM-1), (YLIM-1) ]
@//E*O*F vecdem.h//
chmod u=rw,g=r,o=r vecdem.h
echo x - demo.p
sed 's/^@//' > "demo.p" <<'@//E*O*F demo.p//'
c Demo code segment to illustrate some PREP facilities. This is
c just a preprocessor demo and will not compile without adding
c a lot of variable declarations.
#include "prepmac.h"
c flag to call alternate window filler if window size = array size
: PIXIE_FLAG (((xpix1-xpix0+1) == nrows) & ((ypix1-ypix0+1) == ncols))) ;
include 'tencomn'
c open the input data file and initialize the device
call init
c skip over skip0 data sets
call skipdat( skip0 )
if (eoflag) call exodus
c enter the menu
call menu
c read data tables from the input file and plot until empty
begin
c clear the record numbers
do j = 1, 10
record( j ) = 0
end_do
do j = 1, 10
icount = j
call getdat
record( icount ) = first_record
leave_do (eoflag)
c on first dataset of a group reset background
if ( icount .eq. 1 ) then
call vsbcol(dev, backcol)
call vclrwk(dev)
end if
c weed the data to make it fit in the window
call compact
c clear a window and label it
call windower
c Plot the data table , 1st arg is absolute first dim of buffer
if ( PIXIE_FLAG ) then
call pixie( HARD_X_DIM, nrows, ncols,
* xpix0, PHYS_HEIGHT - 1 - ypix1,
* buffer )
else
call winfill( HARD_X_DIM, nrows, ncols,
* xpix0, xpix1,
* PHYS_HEIGHT - 1 - ypix1,
* PHYS_HEIGHT - 1 - ypix0,
* buffer )
end if
c see if the user is tired and wants to quit
status = vsmstr( dev, ten, zero, echoxy, dummy)
if ( status .gt. 0 ) then
case [ upper( dummy(1:1) ) ]
of ( 'Q' ) call exodus
of ( 'R' ) leave_do
of ( 'B' ) leave_do
end_case
end if
end_do
c skip over skip data sets
call skipdat( skip )
c Delay and wait for keystroke. Quit on Q,q; continue on cr; enlarge
c on keys 1,2,3,...9,0 (0 --> 10); make a dump file on D, d.
c If in movie mode, skip this input section, make a dump, and continue
if ( movie_mode ) then
if (eoflag) call exodus
call dump
else
c stay in this loop if end of file has been reached.
begin
case ( last_key )
last_key = key(dev)
of ( 'D' ) call dump
continue_case
of ( 'Q' ) call exodus
of ( 'R' ) call restart
of ( 'B' ) call pop( recn )
recn = max0( recn, 1 )
eoflag = .false.
default call push( max0( record(1), 1 ) )
call enlarger
end_case
while ( eoflag )
again
end if
again
c Restore the video mode and turn off the device
call exodus
end
@//E*O*F demo.p//
chmod u=rw,g=r,o=r demo.p
echo x - sieve.p
sed 's/^@//' > "sieve.p" <<'@//E*O*F sieve.p//'
c sieve benchmark in fortran
#include "prepmac.h"
: S 8190 ;
: WHILE(l) begin
while (l) ;
do limits [ (0, S) ]
integer f(S+1), i, p, k, c, n
do n = 1, 10
c = 0
f(#) = 1
[ if ( f(#) != 0 ) then
p = # + # + 3
k = # + p
WHILE ( k <= S )
f(k) = 0
k = k + p
again
c = c + 1
end if
]
enddo
write(*,*) c, ' primes'
stop
end
@//E*O*F sieve.p//
chmod u=rw,g=r,o=r sieve.p
echo x - vecdem.p
sed 's/^@//' > "vecdem.p" <<'@//E*O*F vecdem.p//'
c Demo to demonstrate some PREP facilities. This program is a demo
c only and will not compile without a lot of variable definitions.
#include "vecdem.h"
subroutine w_accel_l(psi, lin_fac, source, omega)
include "ellipdim"
if (w_bypass) return
w_error = FALSE
c Set up the basis consisting of past iterates
[ basis(#,#,1) = psi(#,#)
basis(#,#,2) = psi(#,#) - psi_alt(#,#,1)
basis(#,#,3) = psi(#,#) - 2*psi_alt(#,#,1) + psi_alt(#,#,2)
basis(#,#,4) = 1 ]
PERIODIC( basis1 )
PERIODIC( basis2 )
PERIODIC( basis3 )
PERIODIC( basis4 )
c Calculate the matrix and the source vector
do i = 1, w_dim
ii = i
do j = i, w_dim
jj = j
call make_mat_l(psi, lin_fac, source, omega, i, j)
end_do
end_do
do i = 1, w_dim
w_source(i) = 0
w_source(i) = source(#,#)*basis(#,#,i) + w_source(i)
end_do
c invert the symmetric matrix
call linsys(w_matrix, w_dim, w_dim, w_source, w_coeff, ising, lfirst,
* lprint, work)
if (ising == 1) then
write(*,*) ' WARNING: W_matrix is singular '
w_error = TRUE
return
endif
c calculate the improved solution
psi(#,#) = 0
do i = 1, w_dim
psi(#,#) = psi(#,#) + w_coeff(i)*basis(#,#,i)
end_do
c output section for error checking
do i = 1, w_dim
write(*,100) i, .5*w_matrix(i,i) - w_source(i),
* i, w_coeff(i)
end_do
do_limits = { w_dim }
action = 0
do i = 1, w_dim
action = action + w_matrix(i,#)*w_coeff(i)*w_coeff(#)
end_do
action = action/2
action = action - w_source(#)*w_coeff(#)
write(*,*) ' new action = ',action
return
100 format(' action(',i1')= ',g16.9,' w_coeff(',i1,')= ', g16.9)
end
@//E*O*F vecdem.p//
chmod u=rw,g=r,o=r vecdem.p
echo x - vecdemo.p
sed 's/^@//' > "vecdemo.p" <<'@//E*O*F vecdemo.p//'
c***********************************************************************
c *
c subroutine W_ACCEL_LIN *
c *
c Do the Wachspress accelleration. *
c The solution is expressed as a linear combination of the previous *
c iterate and the lowest order fourier modes and the coefficients *
c are found so as to minimize the error. *
c *
c P.R.OVE 7/6/85 *
c***********************************************************************
subroutine w_accel_l(psi, lin_fac, source, omega)
use ellipdim
do_limits = { mx, my }
if (w_bypass) return
w_error = FALSE
c**********************************************************************
c Set up the basis consisting of past iterates *
c**********************************************************************
[ basis(#,#,1) = psi(#,#)
basis(#,#,2) = psi(#,#) - psi_alt(#,#,1)
basis(#,#,3) = psi(#,#) - 2*psi_alt(#,#,1) + psi_alt(#,#,2)
basis(#,#,4) = 1 ]
call periodic( mx, my, basis1 )
call periodic( mx, my, basis2 )
call periodic( mx, my, basis3 )
call periodic( mx, my, basis4 )
c**********************************************************************
c Calculate the Wachspress matrix and the source vector *
c**********************************************************************
do i = 1, w_dim
ii = i
do j = i, w_dim
jj = j
call make_mat_l(psi, lin_fac, source, omega, i, j)
end_do
end_do
do i = 1, w_dim
w_source(i) = 0
w_source(i) = source(#,#)*basis(#,#,i) + w_source(i)
end_do
c**********************************************************************
c invert the symmetric matrix and improve the solution psi. *
c**********************************************************************
call linsys(w_matrix, w_dim, w_dim, w_source, w_coeff,
* ising, lfirst, lprint, work)
if (ising == 1) then
c write(*,*) ' WARNING: W_matrix is singular '
w_error = TRUE
goto 99
endif
c calculate the improved solution
psi(#,#) = 0
do i = 1, w_dim
psi(#,#) = psi(#,#) + w_coeff(i)*basis(#,#,i)
end_do
c**********************************************************************
c output section for error checking (optional) *
c**********************************************************************
go to 99
do i = 1, w_dim
write(*,100) i, .5*w_matrix(i,i) - w_source(i),
* i, w_coeff(i)
100 format(' action(',i1')= ',g16.9,' w_coeff(',i1,')= ',
* g16.9)
end_do
do_limits = { w_dim }
action = 0
do i = 1, w_dim
action = action + w_matrix(i,#)*w_coeff(i)*w_coeff(#)
end_do
action = action/2
action = action - w_source(#)*w_coeff(#)
write(*,*) ' new action = ',action
99 return
end
@//E*O*F vecdemo.p//
chmod u=rw,g=r,o=r vecdemo.p
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
750 2967 17527 flow.c
807 3353 18498 misc.c
13 55 243 fix.h
23 65 414 macro.h
97 566 3740 prep.h
74 268 1826 prepdf.h
22 81 326 prepmac.h
18 46 326 string.h
19 80 408 vecdem.h
113 441 3190 demo.p
30 91 402 sieve.p
71 241 1870 vecdem.p
87 316 3336 vecdemo.p
2124 8570 52106 total
!!!
wc flow.c misc.c fix.h macro.h prep.h prepdf.h prepmac.h string.h vecdem.h demo.p sieve.p vecdem.p vecdemo.p | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0