A example umacr1.c is given below. The name of the user macro is set to revr. The macro itself is used for translating binary restart files from systems that place the leading bit first in a word to systems that place it last and vice-versa. The use of C as opposed to Fortran is employed here merely for the purposes of illustrating how to interface to C code. The same operation could like have been written in Fortran also.
The command itself takes one argument, the name of the original restart file, and outputs a word swapped version of the file using the same name appended with the suffix ".rev".
#include <stdio.h> /* C Header for input/output needed for this particular user macro routine */
struct {
/* C definition for common block umac1.h */
char uct[4];
} umac1_;
struct {
/*C definition for common block sdata.h */
int ndf, ndm, nen1, nst, nneq;
} sdata_;
struct {
/* C definition for common block cdata.h */
int numnp, numel, nummat, nen, neq, ipr;
} cdata_;
void umacr1_(char (* lct)[15],double (* ctl)[3], int *prt)
/* Use trailing underscore for C routine names; define input types */
{
/* F E A P A Finite Element Analysis Program
Copyright (c) 1984-1999: Robert L. Taylor
Purpose: User interface for adding
solution command language
instructions. C language interface by Sanjay Govindjee
Inputs:
(*lct) - Pointer
to Command character parameter string 15
(*ctl)[3] - Command numerical parameters
*prt - Flag, output if
true
Outputs:
N.B. Users are responsible for command actions. See
programmers manual for example.
*/
double get_put_double(FILE *,FILE *); /* define variables that you will be using */
int i,get_put_integer(FILE *,FILE
*);
int nnpo,nnlo,nnmo,ndmo,ndfo,fl9sg,dummyi;
int md,mq,nrt,nh1,nh2;
FILE *fp , *fpout;
char out[20];
void get_put_header(FILE *,FILE
*);
/* Set macro name to REVR in common
block umac1 */ /*Set
uct variable to name you desire if uct = mac1 */
if( strcmp(umac1_.uct,"mac1")==0
) {
/* command will be known to FEAP as REVR
*/
strcpy(umac1_.uct,"revr");
return;
}
/* From here down is the source that gets executed
when one calls REVR from FEAP;
most of it is associated with the vagaries
of C and Fortran file formats and handling.
The order of the reading etc. is compatible
with FEAP v7.1f */
/* Compact lct to strip trailing
blanks */ /*
LCT comes in with blanks that pad the string to length 15 */
for(i=0;i<15;i++) if ( (*lct)[i]
== ' ') break; /*
with C these need to be stripped; do by inserting an EOS marker */
(*lct)[i] = '\0';
/* Open restart file */
if((fp = fopen((*lct),"r")) ==
NULL) {
printf("ERROR * *
Can not open file %s\n",lct);
return;
}
/* Open revised restart file */
strcpy(out,(*lct));
strcat(out,".rev");
if((fpout = fopen(out,"w")) ==
NULL) {
printf("ERROR * *
Can not open file %s\n",out);
if(fp != NULL) fclose(fp);
return;
}
/* Read/Write line 1 */
get_put_header(fp,fpout);
nnpo = get_put_integer(fp,fpout);
nnlo = get_put_integer(fp,fpout);
nnmo = get_put_integer(fp,fpout);
ndmo = get_put_integer(fp,fpout);
ndfo = get_put_integer(fp,fpout);
fl9sg = get_put_integer(fp,fpout);
get_put_header(fp,fpout);
if ( nnpo != cdata_.numnp
|| nnlo != cdata_.numel ||
nnmo != cdata_.nummat || ndmo != sdata_.ndm ||
ndfo != sdata_.ndf ) {
printf("\nERROR * * Restart file does not match input file\n");
fclose(fp);
fclose(fpout);
return;
}
/* Read/Write line 2 */
get_put_header(fp,fpout);
for(i=0;i<3;i++) get_put_double(fp,fpout);
/* theta(3) */
/* nrk,nrc,nrm */
for(i=0;i<3;i++) get_put_integer(fp,fpout);
nrt = get_put_integer(fp,fpout);
/* noi,numint */
for(i=0;i<2;i++) get_put_integer(fp,fpout);
/* alpha, gtan(3) */
for(i=0;i<4;i++) get_put_double(fp,fpout);
get_put_header(fp,fpout);
/* Read/Write line 3 */
get_put_header(fp,fpout);
get_put_integer(fp,fpout);
/* ntstep */
/* ttim, dt */
for(i=0;i<2;i++) get_put_double(fp,fpout);
/* u(nneq*3) */
for(i=0;i<sdata_.nneq*3;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
/* Read/Write line 4 */
get_put_header(fp,fpout);
md = get_put_integer(fp,fpout);
get_put_integer(fp,fpout);
/* mv */
get_put_integer(fp,fpout);
/* mf */
mq = get_put_integer(fp,fpout);
get_put_header(fp,fpout);
if( md != 0 ) {
/* Read/Write
line 4b */
get_put_header(fp,fpout);
/* EVAL */
for(i=0;i<mq;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
/* Read/Write
line 4c */
get_put_header(fp,fpout);
/* EVEC*/
for(i=0;i<mq*cdata_.neq;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
}
/* Read/Write line 5 */
get_put_header(fp,fpout);
/* prop,rlnew,c0,cs01,cs02,ds0,r,det0,xn
*/
for(i=0;i<9;i++) get_put_double(fp,fpout);
fl9sg = get_put_integer(fp,fpout);
/* fl9 */
get_put_header(fp,fpout);
if ( fl9sg != 0 ) {
/* Read/Write
line 5a */
get_put_header(fp,fpout);
/* VEL */
for(i=0;i<nrt*sdata_.nneq;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
}
/* Read/Write line 6 */
get_put_header(fp,fpout);
/* FTN */
for(i=0;i<4*sdata_.nneq;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
/* Read/Write line 7 */
get_put_header(fp,fpout);
get_put_double(fp,fpout);
/* rnmax */
nh1 = get_put_integer(fp,fpout);
nh2 = get_put_integer(fp,fpout);
/* H */
for(i=0;i<nh2-nh1+1;i++)
get_put_double(fp,fpout);
get_put_header(fp,fpout);
/* Close files */
fclose(fpout);
fclose(fp);
}
double get_put_double(FILE *fpi,FILE *fpo) {
/* Read 8 bytes for a double and then write it out in reverse */
union {
char c[8];
double value;
} double_var;
int i;
for(i=7;i>-1;i--) double_var.c[i] = getc(fpi);
for(i=0;i<8;i++) putc(double_var.c[i],fpo);
return(double_var.value);
}
int get_put_integer(FILE *fpi,FILE *fpo) {
/* Read 4 bytes for a integer and then write it out in reverse */
union {
char c[4];
int value;
} int_var;
int i;
for(i=3;i>-1;i--) int_var.c[i] = getc(fpi);
for(i=0;i<4;i++) putc(int_var.c[i],fpo);
return(int_var.value);
}
void get_put_header(FILE *fpi,FILE *fpo) {
/* Read 4 bytes for the recorde header/trailer and write it out in
reverse */
char c[4];
int i;
for(i=3;i>-1;i--) c[i] = getc(fpi);
for(i=0;i<4;i++) putc(c[i],fpo);
return;
}
%