112554Scsvaf /* Copyright (c) 1982 Regents of the University of California */ 212554Scsvaf 3*14652Slinton static char sccsid[] = "@(#)fortran.c 1.4 08/16/83"; 412554Scsvaf 512549Scsvaf /* 612549Scsvaf * FORTRAN dependent symbol routines. 712549Scsvaf */ 812549Scsvaf 912549Scsvaf #include "defs.h" 1012549Scsvaf #include "symbols.h" 1112549Scsvaf #include "printsym.h" 1212549Scsvaf #include "languages.h" 1312549Scsvaf #include "fortran.h" 1412549Scsvaf #include "tree.h" 1512549Scsvaf #include "eval.h" 1612549Scsvaf #include "operators.h" 1712549Scsvaf #include "mappings.h" 1812549Scsvaf #include "process.h" 1912549Scsvaf #include "runtime.h" 2012549Scsvaf #include "machine.h" 2112549Scsvaf 2212549Scsvaf #define isfloat(range) ( \ 2312549Scsvaf range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \ 2412549Scsvaf ) 2512549Scsvaf 2612549Scsvaf #define isrange(t, name) (t->class == RANGE and istypename(t->type, name)) 2712549Scsvaf 2812549Scsvaf #define MAXDIM 20 2912549Scsvaf /* 3012549Scsvaf * Initialize FORTRAN language information. 3112549Scsvaf */ 3212549Scsvaf 3312549Scsvaf public fortran_init() 3412549Scsvaf { 3512549Scsvaf Language lang; 3612549Scsvaf 3712549Scsvaf lang = language_define("fortran", ".f"); 3812549Scsvaf language_setop(lang, L_PRINTDECL, fortran_printdecl); 3912549Scsvaf language_setop(lang, L_PRINTVAL, fortran_printval); 4012549Scsvaf language_setop(lang, L_TYPEMATCH, fortran_typematch); 4112549Scsvaf language_setop(lang, L_BUILDAREF, fortran_buildaref); 4212549Scsvaf language_setop(lang, L_EVALAREF, fortran_evalaref); 4312549Scsvaf } 4412549Scsvaf 4512549Scsvaf /* 4612549Scsvaf * Test if two types are compatible. 4712549Scsvaf * 4812549Scsvaf * Integers and reals are not compatible since they cannot always be mixed. 4912549Scsvaf */ 5012549Scsvaf 5112549Scsvaf public Boolean fortran_typematch(type1, type2) 5212549Scsvaf Symbol type1, type2; 5312549Scsvaf { 5412549Scsvaf 5512549Scsvaf /* only does integer for now; may need to add others 5612549Scsvaf */ 5712549Scsvaf 5812549Scsvaf Boolean b; 5912549Scsvaf register Symbol t1, t2, tmp; 6012549Scsvaf 6112549Scsvaf t1 = rtype(type1); 6212549Scsvaf t2 = rtype(type2); 6312549Scsvaf if(t1 == nil or t1->type == nil or t2 == nil or t2->type == nil ) b = false; 6412549Scsvaf else { b = (Boolean) ( 6512549Scsvaf (t1 == t2) or 6612549Scsvaf (t1->type == t_int and (istypename(t2->type, "integer") or 6712549Scsvaf istypename(t2->type, "integer*2")) ) or 6812549Scsvaf (t2->type == t_int and (istypename(t1->type, "integer") or 6912549Scsvaf istypename(t1->type, "integer*2")) ) 7012549Scsvaf ); 7112549Scsvaf } 7212549Scsvaf /*OUT fprintf(stderr," %d compat %s %s \n", b, 7312549Scsvaf (t1 == nil or t1->type == nil ) ? "nil" : symname(t1->type), 7412549Scsvaf (t2 == nil or t2->type == nil ) ? "nil" : symname(t2->type) );*/ 7512549Scsvaf return b; 7612549Scsvaf } 7712549Scsvaf 7812549Scsvaf private String typename(s) 7912549Scsvaf Symbol s; 8012549Scsvaf { 8112549Scsvaf int ub; 8212549Scsvaf static char buf[20]; 8312549Scsvaf char *pbuf; 8412549Scsvaf Symbol st,sc; 8512549Scsvaf 8612549Scsvaf if(s->type->class == TYPE) return(symname(s->type)); 8712549Scsvaf 8812549Scsvaf for(st = s->type; st->type->class != TYPE; st = st->type); 8912549Scsvaf 9012549Scsvaf pbuf=buf; 9112549Scsvaf 9212549Scsvaf if(istypename(st->type,"char")) { 9312549Scsvaf sprintf(pbuf,"character*"); 9412549Scsvaf pbuf += strlen(pbuf); 9512549Scsvaf sc = st->chain; 9612549Scsvaf if(sc->symvalue.rangev.uppertype == R_ARG or 9712549Scsvaf sc->symvalue.rangev.uppertype == R_TEMP) { 9812549Scsvaf if( ! getbound(s,sc->symvalue.rangev.upper, 9912549Scsvaf sc->symvalue.rangev.uppertype, &ub) ) 10012549Scsvaf sprintf(pbuf,"(*)"); 10112549Scsvaf else 10212549Scsvaf sprintf(pbuf,"%d",ub); 10312549Scsvaf } 10412549Scsvaf else sprintf(pbuf,"%d",sc->symvalue.rangev.upper); 10512549Scsvaf } 10612549Scsvaf else { 10712549Scsvaf sprintf(pbuf,"%s ",symname(st->type)); 10812549Scsvaf } 10912549Scsvaf return(buf); 11012549Scsvaf } 11112549Scsvaf 11212549Scsvaf private Symbol mksubs(pbuf,st) 11312549Scsvaf Symbol st; 11412549Scsvaf char **pbuf; 11512549Scsvaf { 11612549Scsvaf int lb, ub; 11712549Scsvaf Symbol r, eltype; 11812549Scsvaf 11912549Scsvaf if(st->class != ARRAY or (istypename(st->type, "char")) ) return; 12012549Scsvaf else { 12112549Scsvaf mksubs(pbuf,st->type); 12212549Scsvaf assert( (r = st->chain)->class == RANGE); 12312549Scsvaf 12412549Scsvaf if(r->symvalue.rangev.lowertype == R_ARG or 12512549Scsvaf r->symvalue.rangev.lowertype == R_TEMP) { 12612549Scsvaf if( ! getbound(st,r->symvalue.rangev.lower, 12712549Scsvaf r->symvalue.rangev.lowertype, &lb) ) 12812549Scsvaf sprintf(*pbuf,"?:"); 12912549Scsvaf else 13012549Scsvaf sprintf(*pbuf,"%d:",lb); 13112549Scsvaf } 13212549Scsvaf else { 13312549Scsvaf lb = r->symvalue.rangev.lower; 13412549Scsvaf sprintf(*pbuf,"%d:",lb); 13512549Scsvaf } 13612549Scsvaf *pbuf += strlen(*pbuf); 13712549Scsvaf 13812549Scsvaf if(r->symvalue.rangev.uppertype == R_ARG or 13912549Scsvaf r->symvalue.rangev.uppertype == R_TEMP) { 14012549Scsvaf if( ! getbound(st,r->symvalue.rangev.upper, 14112549Scsvaf r->symvalue.rangev.uppertype, &ub) ) 14212549Scsvaf sprintf(*pbuf,"?,"); 14312549Scsvaf else 14412549Scsvaf sprintf(*pbuf,"%d,",ub); 14512549Scsvaf } 14612549Scsvaf else { 14712549Scsvaf ub = r->symvalue.rangev.upper; 14812549Scsvaf sprintf(*pbuf,"%d,",ub); 14912549Scsvaf } 15012549Scsvaf *pbuf += strlen(*pbuf); 15112549Scsvaf 15212549Scsvaf } 15312549Scsvaf } 15412549Scsvaf 15512549Scsvaf /* 15612549Scsvaf * Print out the declaration of a FORTRAN variable. 15712549Scsvaf */ 15812549Scsvaf 15912549Scsvaf public fortran_printdecl(s) 16012549Scsvaf Symbol s; 16112549Scsvaf { 16212549Scsvaf 16312549Scsvaf 16412549Scsvaf Symbol eltype; 16512549Scsvaf 16612549Scsvaf switch (s->class) { 16712549Scsvaf case CONST: 16812549Scsvaf printf("parameter %s = ", symname(s)); 16912549Scsvaf printval(s); 17012549Scsvaf break; 17112549Scsvaf 17212549Scsvaf case REF: 17312549Scsvaf printf(" (dummy argument) "); 174*14652Slinton /* fall through */ 175*14652Slinton case VAR: 176*14652Slinton if (s->type->class == ARRAY and 177*14652Slinton (not istypename(s->type->type, "char")) 178*14652Slinton ) { 179*14652Slinton char bounds[130], *p1, **p; 18012549Scsvaf 18112549Scsvaf p1 = bounds; 18212549Scsvaf p = &p1; 183*14652Slinton mksubs(p, s->type); 18412549Scsvaf *p -= 1; 18512549Scsvaf **p = '\0'; /* get rid of trailing ',' */ 186*14652Slinton printf(" %s %s[%s] ", typename(s), symname(s), bounds); 18712549Scsvaf } else { 18812549Scsvaf printf("%s %s", typename(s), symname(s)); 18912549Scsvaf } 19012549Scsvaf break; 19112549Scsvaf 19212549Scsvaf case FUNC: 19312627Scsvaf if (not istypename(s->type, "void")) { 19412549Scsvaf printf(" %s function ", typename(s) ); 195*14652Slinton } else { 196*14652Slinton printf(" subroutine"); 19712549Scsvaf } 19812549Scsvaf printf(" %s ", symname(s)); 19912549Scsvaf fortran_listparams(s); 20012549Scsvaf break; 20112549Scsvaf 20212549Scsvaf case MODULE: 203*14652Slinton printf("source file \"%s.f\"", symname(s)); 20412549Scsvaf break; 20512549Scsvaf 20612549Scsvaf case PROG: 20712549Scsvaf printf("executable file \"%s\"", symname(s)); 20812549Scsvaf break; 20912549Scsvaf 21012549Scsvaf default: 21112549Scsvaf error("class %s in fortran_printdecl", classname(s)); 21212549Scsvaf } 21312549Scsvaf putchar('\n'); 21412549Scsvaf } 21512549Scsvaf 21612549Scsvaf /* 21712549Scsvaf * List the parameters of a procedure or function. 21812549Scsvaf * No attempt is made to combine like types. 21912549Scsvaf */ 22012549Scsvaf 22112549Scsvaf public fortran_listparams(s) 22212549Scsvaf Symbol s; 22312549Scsvaf { 22412549Scsvaf register Symbol t; 22512549Scsvaf 22612549Scsvaf putchar('('); 22712549Scsvaf for (t = s->chain; t != nil; t = t->chain) { 22812549Scsvaf printf("%s", symname(t)); 22912549Scsvaf if (t->chain != nil) { 23012549Scsvaf printf(", "); 23112549Scsvaf } 23212549Scsvaf } 23312549Scsvaf putchar(')'); 23412549Scsvaf if (s->chain != nil) { 23512549Scsvaf printf("\n"); 23612549Scsvaf for (t = s->chain; t != nil; t = t->chain) { 23712549Scsvaf if (t->class != REF) { 23812549Scsvaf panic("unexpected class %d for parameter", t->class); 23912549Scsvaf } 24012549Scsvaf printdecl(t, 0); 24112549Scsvaf } 24212549Scsvaf } else { 24312549Scsvaf putchar('\n'); 24412549Scsvaf } 24512549Scsvaf } 24612549Scsvaf 24712549Scsvaf /* 24812549Scsvaf * Print out the value on the top of the expression stack 24912549Scsvaf * in the format for the type of the given symbol. 25012549Scsvaf */ 25112549Scsvaf 25212549Scsvaf public fortran_printval(s) 25312549Scsvaf Symbol s; 25412549Scsvaf { 25512549Scsvaf register Symbol t; 25612549Scsvaf register Address a; 25712549Scsvaf register int i, len; 25812549Scsvaf 25912549Scsvaf /* printf("fortran_printval with class %s \n",classname(s)); OUT*/ 26012549Scsvaf switch (s->class) { 26112549Scsvaf case CONST: 26212549Scsvaf case TYPE: 26312549Scsvaf case VAR: 26412549Scsvaf case REF: 26512549Scsvaf case FVAR: 26612549Scsvaf case TAG: 26712549Scsvaf fortran_printval(s->type); 26812549Scsvaf break; 26912549Scsvaf 27012549Scsvaf case ARRAY: 27112549Scsvaf t = rtype(s->type); 27212549Scsvaf if (t->class == RANGE and istypename(t->type, "char")) { 27312549Scsvaf len = size(s); 27412549Scsvaf sp -= len; 27512549Scsvaf printf("\"%.*s\"", len, sp); 27612549Scsvaf } else { 27712549Scsvaf fortran_printarray(s); 27812549Scsvaf } 27912549Scsvaf break; 28012549Scsvaf 28112549Scsvaf case RANGE: 28212549Scsvaf if (isfloat(s)) { 28312549Scsvaf switch (s->symvalue.rangev.lower) { 28412549Scsvaf case sizeof(float): 28512549Scsvaf prtreal(pop(float)); 28612549Scsvaf break; 28712549Scsvaf 28812549Scsvaf case sizeof(double): 28912549Scsvaf if(istypename(s->type,"complex")) { 29012549Scsvaf printf("("); 29112549Scsvaf prtreal(pop(float)); 29212549Scsvaf printf(","); 29312549Scsvaf prtreal(pop(float)); 29412549Scsvaf printf(")"); 29512549Scsvaf } 29612549Scsvaf else prtreal(pop(double)); 29712549Scsvaf break; 29812549Scsvaf 29912549Scsvaf default: 30012549Scsvaf panic("bad size \"%d\" for real", 30112549Scsvaf t->symvalue.rangev.lower); 30212549Scsvaf break; 30312549Scsvaf } 30412549Scsvaf } else { 30512549Scsvaf printint(popsmall(s), s); 30612549Scsvaf } 30712549Scsvaf break; 30812549Scsvaf 30912549Scsvaf default: 31012549Scsvaf if (ord(s->class) > ord(TYPEREF)) { 31112549Scsvaf panic("printval: bad class %d", ord(s->class)); 31212549Scsvaf } 31312549Scsvaf error("don't know how to print a %s", fortran_classname(s)); 31412549Scsvaf /* NOTREACHED */ 31512549Scsvaf } 31612549Scsvaf } 31712549Scsvaf 31812549Scsvaf /* 31912549Scsvaf * Print out an int 32012549Scsvaf */ 32112549Scsvaf 32212549Scsvaf private printint(i, t) 32312549Scsvaf Integer i; 32412549Scsvaf register Symbol t; 32512549Scsvaf { 32612549Scsvaf if (istypename(t->type, "logical")) { 32712549Scsvaf printf(((Boolean) i) == true ? "true" : "false"); 32812549Scsvaf } 32912549Scsvaf else if ( (t->type == t_int) or istypename(t->type, "integer") or 33012549Scsvaf istypename(t->type,"integer*2") ) { 33112549Scsvaf printf("%ld", i); 33212549Scsvaf } else { 33312549Scsvaf error("unkown type in fortran printint"); 33412549Scsvaf } 33512549Scsvaf } 33612549Scsvaf 33712549Scsvaf /* 33812549Scsvaf * Print out a null-terminated string (pointer to char) 33912549Scsvaf * starting at the given address. 34012549Scsvaf */ 34112549Scsvaf 34212549Scsvaf private printstring(addr) 34312549Scsvaf Address addr; 34412549Scsvaf { 34512549Scsvaf register Address a; 34612549Scsvaf register Integer i, len; 34712549Scsvaf register Boolean endofstring; 34812549Scsvaf union { 34912549Scsvaf char ch[sizeof(Word)]; 35012549Scsvaf int word; 35112549Scsvaf } u; 35212549Scsvaf 35312549Scsvaf putchar('"'); 35412549Scsvaf a = addr; 35512549Scsvaf endofstring = false; 35612549Scsvaf while (not endofstring) { 35712549Scsvaf dread(&u, a, sizeof(u)); 35812549Scsvaf i = 0; 35912549Scsvaf do { 36012549Scsvaf if (u.ch[i] == '\0') { 36112549Scsvaf endofstring = true; 36212549Scsvaf } else { 36312549Scsvaf printchar(u.ch[i]); 36412549Scsvaf } 36512549Scsvaf ++i; 36612549Scsvaf } while (i < sizeof(Word) and not endofstring); 36712549Scsvaf a += sizeof(Word); 36812549Scsvaf } 36912549Scsvaf putchar('"'); 37012549Scsvaf } 37112549Scsvaf /* 37212549Scsvaf * Return the FORTRAN name for the particular class of a symbol. 37312549Scsvaf */ 37412549Scsvaf 37512549Scsvaf public String fortran_classname(s) 37612549Scsvaf Symbol s; 37712549Scsvaf { 37812549Scsvaf String str; 37912549Scsvaf 38012549Scsvaf switch (s->class) { 38112549Scsvaf case REF: 38212549Scsvaf str = "dummy argument"; 38312549Scsvaf break; 38412549Scsvaf 38512549Scsvaf case CONST: 38612549Scsvaf str = "parameter"; 38712549Scsvaf break; 38812549Scsvaf 38912549Scsvaf default: 39012549Scsvaf str = classname(s); 39112549Scsvaf } 39212549Scsvaf return str; 39312549Scsvaf } 39412549Scsvaf 39512549Scsvaf /* reverses the indices from the expr_list; should be folded into buildaref 39612549Scsvaf * and done as one recursive routine 39712549Scsvaf */ 39812549Scsvaf Node private rev_index(here,n) 39912549Scsvaf register Node here,n; 40012549Scsvaf { 40112549Scsvaf 40212549Scsvaf register Node i; 40312549Scsvaf 40412549Scsvaf if( here == nil or here == n) i=nil; 40512549Scsvaf else if( here->value.arg[1] == n) i = here; 40612549Scsvaf else i=rev_index(here->value.arg[1],n); 40712549Scsvaf return i; 40812549Scsvaf } 40912549Scsvaf 41012549Scsvaf public Node fortran_buildaref(a, slist) 41112549Scsvaf Node a, slist; 41212549Scsvaf { 41312549Scsvaf register Symbol as; /* array of array of .. cursor */ 41412549Scsvaf register Node en; /* Expr list cursor */ 41512549Scsvaf Symbol etype; /* Type of subscript expr */ 41612549Scsvaf Node esub, tree; /* Subscript expression ptr and tree to be built*/ 41712549Scsvaf 41812549Scsvaf tree=a; 41912549Scsvaf 42012549Scsvaf as = rtype(tree->nodetype); /* node->sym.type->array*/ 42112549Scsvaf if ( not ( 42212549Scsvaf (tree->nodetype->class == VAR or tree->nodetype->class == REF) 42312549Scsvaf and as->class == ARRAY 42412549Scsvaf ) ) { 42512549Scsvaf beginerrmsg(); 42612549Scsvaf prtree(stderr, a); 42712549Scsvaf fprintf(stderr, " is not an array"); 42812549Scsvaf /*fprintf(stderr, " a-> %x as %x ", tree->nodetype, as ); OUT*/ 42912549Scsvaf enderrmsg(); 43012549Scsvaf } else { 43112549Scsvaf for (en = rev_index(slist,nil); en != nil and as->class == ARRAY; 43212549Scsvaf en = rev_index(slist,en), as = as->type) { 43312549Scsvaf esub = en->value.arg[0]; 43412549Scsvaf etype = rtype(esub->nodetype); 43512549Scsvaf assert(as->chain->class == RANGE); 43612549Scsvaf if ( not compatible( t_int, etype) ) { 43712549Scsvaf beginerrmsg(); 43812549Scsvaf fprintf(stderr, "subscript "); 43912549Scsvaf prtree(stderr, esub); 44012549Scsvaf fprintf(stderr, " is type %s ",symname(etype->type) ); 44112549Scsvaf enderrmsg(); 44212549Scsvaf } 44312549Scsvaf tree = build(O_INDEX, tree, esub); 44412549Scsvaf tree->nodetype = as->type; 44512549Scsvaf } 44612549Scsvaf if (en != nil or 44712549Scsvaf (as->class == ARRAY && (not istypename(as->type,"char"))) ) { 44812549Scsvaf beginerrmsg(); 44912549Scsvaf if (en != nil) { 45012549Scsvaf fprintf(stderr, "too many subscripts for "); 45112549Scsvaf } else { 45212549Scsvaf fprintf(stderr, "not enough subscripts for "); 45312549Scsvaf } 45412549Scsvaf prtree(stderr, tree); 45512549Scsvaf enderrmsg(); 45612549Scsvaf } 45712549Scsvaf } 45812549Scsvaf return tree; 45912549Scsvaf } 46012549Scsvaf 46112549Scsvaf /* 46212549Scsvaf * Evaluate a subscript index. 46312549Scsvaf */ 46412549Scsvaf 46512549Scsvaf public int fortran_evalaref(s, i) 46612549Scsvaf Symbol s; 46712549Scsvaf long i; 46812549Scsvaf { 46912549Scsvaf Symbol r; 47012549Scsvaf long lb, ub; 47112549Scsvaf 47212549Scsvaf r = rtype(s)->chain; 47312549Scsvaf if(r->symvalue.rangev.lowertype == R_ARG or 47412549Scsvaf r->symvalue.rangev.lowertype == R_TEMP ) { 47512549Scsvaf if(! getbound(s,r->symvalue.rangev.lower, 47612549Scsvaf r->symvalue.rangev.lowertype,&lb)) 47712549Scsvaf error("dynamic bounds not currently available"); 47812549Scsvaf } 47912549Scsvaf else lb = r->symvalue.rangev.lower; 48012549Scsvaf 48112549Scsvaf if(r->symvalue.rangev.uppertype == R_ARG or 48212549Scsvaf r->symvalue.rangev.uppertype == R_TEMP ) { 48312549Scsvaf if(! getbound(s,r->symvalue.rangev.upper, 48412549Scsvaf r->symvalue.rangev.uppertype,&ub)) 48512549Scsvaf error("dynamic bounds not currently available"); 48612549Scsvaf } 48712549Scsvaf else ub = r->symvalue.rangev.upper; 48812549Scsvaf 48912549Scsvaf if (i < lb or i > ub) { 49012549Scsvaf error("subscript out of range"); 49112549Scsvaf } 49212549Scsvaf return (i - lb); 49312549Scsvaf } 49412549Scsvaf 49512549Scsvaf private fortran_printarray(a) 49612549Scsvaf Symbol a; 49712549Scsvaf { 49812549Scsvaf struct Bounds { int lb, val, ub} dim[MAXDIM]; 49912549Scsvaf 50012549Scsvaf Symbol sc,st,eltype; 50112549Scsvaf char buf[50]; 50212549Scsvaf char *subscr; 50312549Scsvaf int i,ndim,elsize; 50412549Scsvaf Stack *savesp; 50512549Scsvaf Boolean done; 50612549Scsvaf 50712549Scsvaf st = a; 50812549Scsvaf 50912549Scsvaf savesp = sp; 51012549Scsvaf sp -= size(a); 51112549Scsvaf ndim=0; 51212549Scsvaf 51312549Scsvaf for(;;){ 51412549Scsvaf sc = st->chain; 51512549Scsvaf if(sc->symvalue.rangev.lowertype == R_ARG or 51612549Scsvaf sc->symvalue.rangev.lowertype == R_TEMP) { 51712549Scsvaf if( ! getbound(a,sc->symvalue.rangev.lower, 51812627Scsvaf sc->symvalue.rangev.lowertype, &dim[ndim].lb) ) 51912549Scsvaf error(" dynamic bounds not currently available"); 52012549Scsvaf } 52112549Scsvaf else dim[ndim].lb = sc->symvalue.rangev.lower; 52212549Scsvaf 52312549Scsvaf if(sc->symvalue.rangev.uppertype == R_ARG or 52412549Scsvaf sc->symvalue.rangev.uppertype == R_TEMP) { 52512549Scsvaf if( ! getbound(a,sc->symvalue.rangev.upper, 52612549Scsvaf sc->symvalue.rangev.uppertype, &dim[ndim].ub) ) 52712549Scsvaf error(" dynamic bounds not currently available"); 52812549Scsvaf } 52912549Scsvaf else dim[ndim].ub = sc->symvalue.rangev.upper; 53012549Scsvaf 53112549Scsvaf ndim ++; 53212549Scsvaf if (st->type->class == ARRAY) st=st->type; 53312549Scsvaf else break; 53412549Scsvaf } 53512549Scsvaf 53612549Scsvaf if(istypename(st->type,"char")) { 53712549Scsvaf eltype = st; 53812549Scsvaf ndim--; 53912549Scsvaf } 54012549Scsvaf else eltype=st->type; 54112549Scsvaf elsize=size(eltype); 54212549Scsvaf sp += elsize; 54312549Scsvaf /*printf("ndim %d elsize %lx in fortran_printarray\n",ndim,elsize);OUT*/ 54412549Scsvaf 54512549Scsvaf ndim--; 54612549Scsvaf for (i=0;i<=ndim;i++){ 54712549Scsvaf dim[i].val=dim[i].lb; 54812549Scsvaf /*OUT printf(" %d %d %d \n",i,dim[i].lb,dim[i].ub); 54912549Scsvaf fflush(stdout); OUT*/ 55012549Scsvaf } 55112549Scsvaf 55212549Scsvaf 55312549Scsvaf for(;;) { 55412549Scsvaf buf[0]=','; 55512549Scsvaf subscr = buf+1; 55612549Scsvaf 55712549Scsvaf for (i=ndim-1;i>=0;i--) { 55812549Scsvaf 55912549Scsvaf sprintf(subscr,"%d,",dim[i].val); 56012549Scsvaf subscr += strlen(subscr); 56112549Scsvaf } 56212549Scsvaf *--subscr = '\0'; 56312549Scsvaf 56412549Scsvaf for(i=dim[ndim].lb;i<=dim[ndim].ub;i++) { 56512549Scsvaf printf("[%d%s]\t",i,buf); 56612549Scsvaf printval(eltype); 56712549Scsvaf printf("\n"); 56812549Scsvaf sp += 2*elsize; 56912549Scsvaf } 57012549Scsvaf dim[ndim].val=dim[ndim].ub; 57112549Scsvaf 57212549Scsvaf i=ndim-1; 57312549Scsvaf if (i<0) break; 57412549Scsvaf 57512549Scsvaf done=false; 57612549Scsvaf do { 57712549Scsvaf dim[i].val++; 57812549Scsvaf if(dim[i].val > dim[i].ub) { 57912549Scsvaf dim[i].val = dim[i].lb; 58012549Scsvaf if(--i<0) done=true; 58112549Scsvaf } 58212549Scsvaf else done=true; 58312549Scsvaf } 58412549Scsvaf while (not done); 58512549Scsvaf if (i<0) break; 58612549Scsvaf } 58712549Scsvaf } 588