📄 cfortran.h
字号:
#else#define CF_DECLARE_GETARG#define CF_SET_GETARG(ARGC,ARGV)#endif#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */#pragma standard #endif#define ACOMMA ,#define ACOLON ;/*-------------------------------------------------------------------------*//* UTILITIES USED WITHIN CFORTRAN.H */#define _cfMIN(A,B) (A<B?A:B)#define firstindexlength( A) (sizeof(A) /sizeof(A[0]))#define secondindexlength(A) (sizeof((A)[0])/sizeof((A)[0][0]))#ifndef FALSE#define FALSE (1==0)#endif/* Behavior of FORTRAN LOGICAL. All machines' LOGICAL is same size as C's int.Conversion is automatic except for arrays which require F2CLOGICALV/C2FLOGICALV.f2c, MIPS f77 [DECstation, SGI], VAX Ultrix f77, CRAY-2, HP-UX f77: as in C.VAX/VMS FORTRAN, VAX Ultrix fort,Absoft Unix Fortran, IBM RS/6000 xlf : LS Bit = 0/1 = TRUE/FALSE.Apollo, non CRAY-2 : neg. = TRUE, else FALSE. [Apollo accepts -1 as TRUE for function values, but NOT all other neg. values.][DECFortran for Ultrix RISC is also called f77 but is the same as VAX/VMS.] [MIPS f77 treats .eqv./.neqv. as .eq./.ne. and hence requires LOGICAL_STRICT.]*/#if defined(NAGf90Fortran) || defined(f2cFortran) || defined(mipsFortran) || defined(PowerStationFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)/* PowerStationFortran has 0 and 1 defined, others are neither true nor false.*//* hpuxFortran800 has 0 and 0x01000000 defined. Others are unknown. */#define LOGICAL_STRICT /* Other Fortran have .eqv./.neqv. == .eq./.ne. */#endif#define C2FLOGICALV(A,I) \ do {int __i; for(__i=0;__i<I;__i++) A[__i]=C2FLOGICAL(A[__i]); } while (FALSE)#define F2CLOGICALV(A,I) \ do {int __i; for(__i=0;__i<I;__i++) A[__i]=F2CLOGICAL(A[__i]); } while (FALSE)#if defined(apolloFortran) || (defined(CRAYFortran) && !defined(_CRAY2))#ifndef apolloFortran/* (unsigned) avoid 'integer overflow detected: op "<<"' for SunOS Xcompile. */#define C2FLOGICAL(L) ((L)?(L)|((unsigned)1<<sizeof(int)*8-1):(L)&~((unsigned)1<<sizeof(int)*8-1))#else#define C2FLOGICAL(L) ((L)?-1:(L)&~((unsigned)1<<sizeof(int)*8-1)) /* Apollo Exception */#endif#define F2CLOGICAL(L) ((L)<0?(L):0) #else#if defined(IBMR2Fortran) || defined(vmsFortran) || defined(DECFortran) || defined(AbsoftUNIXFortran)#define C2FLOGICAL(L) ((L)?(L)|1:(L)&~(int)1)#define F2CLOGICAL(L) ((L)&1?(L):0)#else#if defined(CONVEXFortran)#define C2FLOGICAL(L) ((L) ? ~0 : 0 )#define F2CLOGICAL(L) (L)#else /* others evaluate LOGICALs as for C. */#define C2FLOGICAL(L) (L)#define F2CLOGICAL(L) (L)#ifndef LOGICAL_STRICT#undef C2FLOGICALV#undef F2CLOGICALV#define C2FLOGICALV(A,I)#define F2CLOGICALV(A,I)#endif /* LOGICAL_STRICT */#endif /* CONVEXFortran || All Others */#endif /* IBMR2Fortran vmsFortran DECFortran */#endif /* apolloFortran CRAYFortran !_CRAY2 */#ifdef LOGICAL_STRICT/* Force C2FLOGICAL to generate only the values for either .TRUE. or .FALSE. PowerStationFortran only has 0 and 1 defined. Elsewhere, only needed if you want to do: logical lvariable if (lvariable .eq. .true.) then ! (1) instead of if (lvariable .eqv. .true.) then ! (2) - (1) may not even be FORTRAN/77 and that Apollo's f77 and IBM's xlf refuse to compile (1), so you are probably well advised to stay away from (1) and from LOGICAL_STRICT. - You pay a (slight) performance penalty for using LOGICAL_STRICT. */#undef C2FLOGICAL#ifdef hpuxFortran800#define C2FLOGICAL(L) ((L)?0x01000000:0)#else#if defined(apolloFortran) || (defined(CRAYFortran) && !defined(_CRAY2)) || defined(vmsFortran) || defined(DECFortran)#define C2FLOGICAL(L) ((L)?-1:0) /* These machines use -1/0 for .true./.false.*/#else#define C2FLOGICAL(L) ((L)? 1:0) /* All others use +1/0 for .true./.false.*/#endif#endif#endif /* LOGICAL_STRICT *//* Convert a vector of C strings into FORTRAN strings. */#ifndef __CF__KnRstatic char *c2fstrv(char* cstr, char *fstr, int elem_len, int sizeofcstr)#elsestatic char *c2fstrv( cstr, fstr, elem_len, sizeofcstr) char* cstr; char *fstr; int elem_len; int sizeofcstr;#endif{ int i,j;/* elem_len includes \0 for C strings. Fortran strings don't have term. \0. Useful size of string must be the same in both languages. */for (i=0; i<sizeofcstr/elem_len; i++) { for (j=1; j<elem_len && *cstr; j++) *fstr++ = *cstr++; cstr += 1+elem_len-j; for (; j<elem_len; j++) *fstr++ = ' ';} /* 95109 - Seems to be returning the original fstr. */return fstr-sizeofcstr+sizeofcstr/elem_len; }/* Convert a vector of FORTRAN strings into C strings. */#ifndef __CF__KnRstatic char *f2cstrv(char *fstr, char* cstr, int elem_len, int sizeofcstr)#elsestatic char *f2cstrv( fstr, cstr, elem_len, sizeofcstr) char *fstr; char* cstr; int elem_len; int sizeofcstr; #endif{ int i,j;/* elem_len includes \0 for C strings. Fortran strings don't have term. \0. Useful size of string must be the same in both languages. */cstr += sizeofcstr;fstr += sizeofcstr - sizeofcstr/elem_len;for (i=0; i<sizeofcstr/elem_len; i++) { *--cstr = '\0'; for (j=1; j<elem_len; j++) *--cstr = *--fstr;} return cstr; }/* kill the trailing char t's in string s. */#ifndef __CF__KnRstatic char *kill_trailing(char *s, char t)#elsestatic char *kill_trailing( s, t) char *s; char t;#endif{char *e; e = s + strlen(s);if (e>s) { /* Need this to handle NULL string.*/ while (e>s && *--e==t); /* Don't follow t's past beginning. */ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */} return s; }/* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally points to the terminating '\0' of s, but may actually point to anywhere in s.s's new '\0' will be placed at e or earlier in order to remove any trailing t's.If e<s string s is left unchanged. */ #ifndef __CF__KnRstatic char *kill_trailingn(char *s, char t, char *e)#elsestatic char *kill_trailingn( s, t, e) char *s; char t; char *e;#endif{ if (e==s) *e = '\0'; /* Kill the string makes sense here.*/else if (e>s) { /* Watch out for neg. length string.*/ while (e>s && *--e==t); /* Don't follow t's past beginning. */ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */} return s; }/* Note the following assumes that any element which has t's to be chopped off,does indeed fill the entire element. */#ifndef __CF__KnRstatic char *vkill_trailing(char* cstr, int elem_len, int sizeofcstr, char t)#elsestatic char *vkill_trailing( cstr, elem_len, sizeofcstr, t) char* cstr; int elem_len; int sizeofcstr; char t;#endif{ int i;for (i=0; i<sizeofcstr/elem_len; i++) /* elem_len includes \0 for C strings. */ kill_trailingn(cstr+elem_len*i,t,cstr+elem_len*(i+1)-1);return cstr; }#ifdef vmsFortrantypedef struct dsc$descriptor_s fstring;#define DSC$DESCRIPTOR_A(DIMCT) \struct { \ unsigned short dsc$w_length; unsigned char dsc$b_dtype; \ unsigned char dsc$b_class; char *dsc$a_pointer; \ char dsc$b_scale; unsigned char dsc$b_digits; \ struct { \ unsigned : 3; unsigned dsc$v_fl_binscale : 1; \ unsigned dsc$v_fl_redim : 1; unsigned dsc$v_fl_column : 1; \ unsigned dsc$v_fl_coeff : 1; unsigned dsc$v_fl_bounds : 1; \ } dsc$b_aflags; \ unsigned char dsc$b_dimct; unsigned long dsc$l_arsize; \ char *dsc$a_a0; long dsc$l_m [DIMCT]; \ struct { \ long dsc$l_l; long dsc$l_u; \ } dsc$bounds [DIMCT]; \}typedef DSC$DESCRIPTOR_A(1) fstringvector;/*typedef DSC$DESCRIPTOR_A(2) fstringarrarr; typedef DSC$DESCRIPTOR_A(3) fstringarrarrarr;*/#define initfstr(F,C,ELEMNO,ELEMLEN) \( (F).dsc$l_arsize= ( (F).dsc$w_length =(ELEMLEN) ) \ *( (F).dsc$l_m[0]=(F).dsc$bounds[0].dsc$l_u=(ELEMNO) ), \ (F).dsc$a_a0 = ( (F).dsc$a_pointer=(C) ) - (F).dsc$w_length ,(F))#else#define _NUM_ELEMS -1#define _NUM_ELEM_ARG -2#define NUM_ELEMS(A) A,_NUM_ELEMS#define NUM_ELEM_ARG(B) *_2(A,B),_NUM_ELEM_ARG#define TERM_CHARS(A,B) A,B#ifndef __CF__KnRstatic int num_elem(char *strv, unsigned elem_len, int term_char, int num_term)#elsestatic int num_elem( strv, elem_len, term_char, num_term) char *strv; unsigned elem_len; int term_char; int num_term;#endif/* elem_len is the number of characters in each element of strv, the FORTRANvector of strings. The last element of the vector must begin with at leastnum_term term_char characters, so that this routine can determine how many elements are in the vector. */{unsigned num,i;if (num_term == _NUM_ELEMS || num_term == _NUM_ELEM_ARG) return term_char;if (num_term <=0) num_term = (int)elem_len;for (num=0; ; num++) { for (i=0; i<(unsigned)num_term && *strv==term_char; i++,strv++); if (i==(unsigned)num_term) break; else strv += elem_len-i;}return (int)num;}#endif/*-------------------------------------------------------------------------*//* UTILITIES FOR C TO USE STRINGS IN FORTRAN COMMON BLOCKS *//* C string TO Fortran Common Block STRing. *//* DIM is the number of DIMensions of the array in terms of strings, not characters. e.g. char a[12] has DIM = 0, char a[12][4] has DIM = 1, etc. */#define C2FCBSTR(CSTR,FSTR,DIM) \ c2fstrv((char *)CSTR, (char *)FSTR, sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \ sizeof(FSTR)+cfelementsof(FSTR,DIM))/* Fortran Common Block string TO C STRing. */#define FCB2CSTR(FSTR,CSTR,DIM) \ vkill_trailing(f2cstrv((char *)FSTR, (char *)CSTR, \ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \ sizeof(FSTR)+cfelementsof(FSTR,DIM)), \ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \ sizeof(FSTR)+cfelementsof(FSTR,DIM), ' ')#define cfDEREFERENCE0#define cfDEREFERENCE1 *#define cfDEREFERENCE2 **#define cfDEREFERENCE3 ***#define cfDEREFERENCE4 ****#define cfDEREFERENCE5 *****#define cfelementsof(A,D) (sizeof(A)/sizeof(_(cfDEREFERENCE,D)(A)))/*-------------------------------------------------------------------------*//* UTILITIES FOR C TO CALL FORTRAN SUBROUTINES *//* Define lookup tables for how to handle the various types of variables. */#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */#pragma nostandard#endif#define ZTRINGV_NUM(I) I#define ZTRINGV_ARGFP(I) (*(_2(A,I))) /* Undocumented. For PINT, etc. */#define ZTRINGV_ARGF(I) _2(A,I)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -