io.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990, 1991, 1993, 1994, 1996, 2000 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 /* Routines to generate code for I/O statements.
00025    Some corrections and improvements due to David Wasley, U. C. Berkeley
00026 */
00027 
00028 /* TEMPORARY */
00029 #define TYIOINT TYLONG
00030 #define SZIOINT SZLONG
00031 
00032 #include "defs.h"
00033 #include "names.h"
00034 #include "iob.h"
00035 
00036 extern int byterev, inqmask;
00037 
00038 static void dofclose Argdcl((void));
00039 static void dofinquire Argdcl((void));
00040 static void dofmove Argdcl((char*));
00041 static void dofopen Argdcl((void));
00042 static void doiolist Argdcl((chainp));
00043 static void ioset Argdcl((int, int, expptr));
00044 static void ioseta Argdcl((int, Addrp));
00045 static void iosetc Argdcl((int, expptr));
00046 static void iosetip Argdcl((int, int));
00047 static void iosetlc Argdcl((int, int, int));
00048 static void putio Argdcl((expptr, expptr));
00049 static void putiocall Argdcl((expptr));
00050 
00051 iob_data *iob_list;
00052 Addrp io_structs[9];
00053 
00054 LOCAL char ioroutine[12];
00055 
00056 LOCAL long ioendlab;
00057 LOCAL long ioerrlab;
00058 LOCAL int endbit;
00059 LOCAL int errbit;
00060 LOCAL long jumplab;
00061 LOCAL long skiplab;
00062 LOCAL int ioformatted;
00063 LOCAL int statstruct = NO;
00064 LOCAL struct Labelblock *skiplabel;
00065 Addrp ioblkp;
00066 
00067 #define UNFORMATTED 0
00068 #define FORMATTED 1
00069 #define LISTDIRECTED 2
00070 #define NAMEDIRECTED 3
00071 
00072 #define V(z)    ioc[z].iocval
00073 
00074 #define IOALL 07777
00075 
00076 LOCAL struct Ioclist
00077 {
00078         char *iocname;
00079         int iotype;
00080         expptr iocval;
00081 }
00082 ioc[ ] =
00083 {
00084         { "", 0 },
00085         { "unit", IOALL },
00086         { "fmt", M(IOREAD) | M(IOWRITE) },
00087         { "err", IOALL },
00088         { "end", M(IOREAD) },
00089         { "iostat", IOALL },
00090         { "rec", M(IOREAD) | M(IOWRITE) },
00091         { "recl", M(IOOPEN) | M(IOINQUIRE) },
00092         { "file", M(IOOPEN) | M(IOINQUIRE) },
00093         { "status", M(IOOPEN) | M(IOCLOSE) },
00094         { "access", M(IOOPEN) | M(IOINQUIRE) },
00095         { "form", M(IOOPEN) | M(IOINQUIRE) },
00096         { "blank", M(IOOPEN) | M(IOINQUIRE) },
00097         { "exist", M(IOINQUIRE) },
00098         { "opened", M(IOINQUIRE) },
00099         { "number", M(IOINQUIRE) },
00100         { "named", M(IOINQUIRE) },
00101         { "name", M(IOINQUIRE) },
00102         { "sequential", M(IOINQUIRE) },
00103         { "direct", M(IOINQUIRE) },
00104         { "formatted", M(IOINQUIRE) },
00105         { "unformatted", M(IOINQUIRE) },
00106         { "nextrec", M(IOINQUIRE) },
00107         { "nml", M(IOREAD) | M(IOWRITE) }
00108 };
00109 
00110 #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
00111 
00112 /* #define IOSUNIT 1 */
00113 /* #define IOSFMT 2 */
00114 #define IOSERR 3
00115 #define IOSEND 4
00116 #define IOSIOSTAT 5
00117 #define IOSREC 6
00118 #define IOSRECL 7
00119 #define IOSFILE 8
00120 #define IOSSTATUS 9
00121 #define IOSACCESS 10
00122 #define IOSFORM 11
00123 #define IOSBLANK 12
00124 #define IOSEXISTS 13
00125 #define IOSOPENED 14
00126 #define IOSNUMBER 15
00127 #define IOSNAMED 16
00128 #define IOSNAME 17
00129 #define IOSSEQUENTIAL 18
00130 #define IOSDIRECT 19
00131 #define IOSFORMATTED 20
00132 #define IOSUNFORMATTED 21
00133 #define IOSNEXTREC 22
00134 #define IOSNML 23
00135 
00136 #define IOSTP V(IOSIOSTAT)
00137 
00138 
00139 /* offsets in generated structures */
00140 
00141 #define SZFLAG SZIOINT
00142 
00143 /* offsets for external READ and WRITE statements */
00144 
00145 #define XERR 0
00146 #define XUNIT   SZFLAG
00147 #define XEND    SZFLAG + SZIOINT
00148 #define XFMT    2*SZFLAG + SZIOINT
00149 #define XREC    2*SZFLAG + SZIOINT + SZADDR
00150 
00151 /* offsets for internal READ and WRITE statements */
00152 
00153 #define XIUNIT  SZFLAG
00154 #define XIEND   SZFLAG + SZADDR
00155 #define XIFMT   2*SZFLAG + SZADDR
00156 #define XIRLEN  2*SZFLAG + 2*SZADDR
00157 #define XIRNUM  2*SZFLAG + 2*SZADDR + SZIOINT
00158 #define XIREC   2*SZFLAG + 2*SZADDR + 2*SZIOINT
00159 
00160 /* offsets for OPEN statements */
00161 
00162 #define XFNAME  SZFLAG + SZIOINT
00163 #define XFNAMELEN       SZFLAG + SZIOINT + SZADDR
00164 #define XSTATUS SZFLAG + 2*SZIOINT + SZADDR
00165 #define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR
00166 #define XFORMATTED      SZFLAG + 2*SZIOINT + 3*SZADDR
00167 #define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR
00168 #define XBLANK  SZFLAG + 3*SZIOINT + 4*SZADDR
00169 
00170 /* offset for CLOSE statement */
00171 
00172 #define XCLSTATUS       SZFLAG + SZIOINT
00173 
00174 /* offsets for INQUIRE statement */
00175 
00176 #define XFILE   SZFLAG + SZIOINT
00177 #define XFILELEN        SZFLAG + SZIOINT + SZADDR
00178 #define XEXISTS SZFLAG + 2*SZIOINT + SZADDR
00179 #define XOPEN   SZFLAG + 2*SZIOINT + 2*SZADDR
00180 #define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR
00181 #define XNAMED  SZFLAG + 2*SZIOINT + 4*SZADDR
00182 #define XNAME   SZFLAG + 2*SZIOINT + 5*SZADDR
00183 #define XNAMELEN        SZFLAG + 2*SZIOINT + 6*SZADDR
00184 #define XQACCESS        SZFLAG + 3*SZIOINT + 6*SZADDR
00185 #define XQACCLEN        SZFLAG + 3*SZIOINT + 7*SZADDR
00186 #define XSEQ    SZFLAG + 4*SZIOINT + 7*SZADDR
00187 #define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR
00188 #define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR
00189 #define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR
00190 #define XFORM   SZFLAG + 6*SZIOINT + 9*SZADDR
00191 #define XFORMLEN        SZFLAG + 6*SZIOINT + 10*SZADDR
00192 #define XFMTED  SZFLAG + 7*SZIOINT + 10*SZADDR
00193 #define XFMTEDLEN       SZFLAG + 7*SZIOINT + 11*SZADDR
00194 #define XUNFMT  SZFLAG + 8*SZIOINT + 11*SZADDR
00195 #define XUNFMTLEN       SZFLAG + 8*SZIOINT + 12*SZADDR
00196 #define XQRECL  SZFLAG + 9*SZIOINT + 12*SZADDR
00197 #define XNEXTREC        SZFLAG + 9*SZIOINT + 13*SZADDR
00198 #define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR
00199 #define XQBLANKLEN      SZFLAG + 9*SZIOINT + 15*SZADDR
00200 
00201 LOCAL char *cilist_names[] = {
00202         "cilist",
00203         "cierr",
00204         "ciunit",
00205         "ciend",
00206         "cifmt",
00207         "cirec"
00208         };
00209 LOCAL char *icilist_names[] = {
00210         "icilist",
00211         "icierr",
00212         "iciunit",
00213         "iciend",
00214         "icifmt",
00215         "icirlen",
00216         "icirnum"
00217         };
00218 LOCAL char *olist_names[] = {
00219         "olist",
00220         "oerr",
00221         "ounit",
00222         "ofnm",
00223         "ofnmlen",
00224         "osta",
00225         "oacc",
00226         "ofm",
00227         "orl",
00228         "oblnk"
00229         };
00230 LOCAL char *cllist_names[] = {
00231         "cllist",
00232         "cerr",
00233         "cunit",
00234         "csta"
00235         };
00236 LOCAL char *alist_names[] = {
00237         "alist",
00238         "aerr",
00239         "aunit"
00240         };
00241 LOCAL char *inlist_names[] = {
00242         "inlist",
00243         "inerr",
00244         "inunit",
00245         "infile",
00246         "infilen",
00247         "inex",
00248         "inopen",
00249         "innum",
00250         "innamed",
00251         "inname",
00252         "innamlen",
00253         "inacc",
00254         "inacclen",
00255         "inseq",
00256         "inseqlen",
00257         "indir",
00258         "indirlen",
00259         "infmt",
00260         "infmtlen",
00261         "inform",
00262         "informlen",
00263         "inunf",
00264         "inunflen",
00265         "inrecl",
00266         "innrec",
00267         "inblank",
00268         "inblanklen"
00269         };
00270 
00271 LOCAL char **io_fields;
00272 
00273 #define zork(n,t) n, sizeof(n)/sizeof(char *) - 1, t
00274 
00275 LOCAL io_setup io_stuff[] = {
00276         zork(cilist_names, TYCILIST),   /* external read/write */
00277         zork(inlist_names, TYINLIST),   /* inquire */
00278         zork(olist_names,  TYOLIST),    /* open */
00279         zork(cllist_names, TYCLLIST),   /* close */
00280         zork(alist_names,  TYALIST),    /* rewind */
00281         zork(alist_names,  TYALIST),    /* backspace */
00282         zork(alist_names,  TYALIST),    /* endfile */
00283         zork(icilist_names,TYICILIST),  /* internal read */
00284         zork(icilist_names,TYICILIST)   /* internal write */
00285         };
00286 
00287 #undef zork
00288 
00289  int
00290 #ifdef KR_headers
00291 fmtstmt(lp)
00292         register struct Labelblock *lp;
00293 #else
00294 fmtstmt(register struct Labelblock *lp)
00295 #endif
00296 {
00297         if(lp == NULL)
00298         {
00299                 execerr("unlabeled format statement" , CNULL);
00300                 return(-1);
00301         }
00302         if(lp->labtype == LABUNKNOWN)
00303         {
00304                 lp->labtype = LABFORMAT;
00305                 lp->labelno = (int)newlabel();
00306         }
00307         else if(lp->labtype != LABFORMAT)
00308         {
00309                 execerr("bad format number", CNULL);
00310                 return(-1);
00311         }
00312         return(lp->labelno);
00313 }
00314 
00315 
00316  void
00317 #ifdef KR_headers
00318 setfmt(lp)
00319         struct Labelblock *lp;
00320 #else
00321 setfmt(struct Labelblock *lp)
00322 #endif
00323 {
00324         char *s, *s0, *sc, *se, *t;
00325         int k, n, parity;
00326 
00327         s0 = s = lexline(&n);
00328         se = t = s + n;
00329 
00330         /* warn of trivial errors, e.g. "  11 CONTINUE" (one too few spaces) */
00331         /* following FORMAT... */
00332 
00333         if (n <= 0)
00334                 warn("No (...) after FORMAT");
00335         else if (*s != '(')
00336                 warni("%c rather than ( after FORMAT", *s);
00337         else if (se[-1] != ')') {
00338                 *se = 0;
00339                 while(--t > s && *t != ')') ;
00340                 if (t <= s)
00341                         warn("No ) at end of FORMAT statement");
00342                 else if (se - t > 30)
00343                         warn1("Extraneous text at end of FORMAT: ...%s", se-12);
00344                 else
00345                         warn1("Extraneous text at end of FORMAT: %s", t+1);
00346                 t = se;
00347                 }
00348 
00349         /* fix MYQUOTES (\002's) and \\'s */
00350 
00351         parity = 1;
00352         str_fmt['%'] = "%";
00353         while(s < se) {
00354                 k = *(unsigned char *)s++;
00355                 if (k == 2) {
00356                         if ((parity ^= 1) && *s == 2) {
00357                                 t -= 2;
00358                                 ++s;
00359                                 }
00360                         else
00361                                 t += 3;
00362                         }
00363                 else {
00364                         sc = str_fmt[k];
00365                         while(*++sc)
00366                                 t++;
00367                         }
00368                 }
00369         s = s0;
00370         parity = 1;
00371         if (lp) {
00372                 lp->fmtstring = t = mem((int)(t - s + 1), 0);
00373                 while(s < se) {
00374                         k = *(unsigned char *)s++;
00375                         if (k == 2) {
00376                                 if ((parity ^= 1) && *s == 2)
00377                                         s++;
00378                                 else {
00379                                         t[0] = '\\';
00380                                         t[1] = '0';
00381                                         t[2] = '0';
00382                                         t[3] = '2';
00383                                         t += 4;
00384                                         }
00385                                 }
00386                         else {
00387                                 sc = str_fmt[k];
00388                                 do *t++ = *sc++;
00389                                    while(*sc);
00390                                 }
00391                         }
00392                 *t = 0;
00393                 }
00394         str_fmt['%'] = "%%";
00395         flline();
00396 }
00397 
00398 
00399  void
00400 #ifdef KR_headers
00401 startioctl()
00402 #else
00403 startioctl()
00404 #endif
00405 {
00406         register int i;
00407 
00408         inioctl = YES;
00409         nioctl = 0;
00410         ioformatted = UNFORMATTED;
00411         for(i = 1 ; i<=NIOS ; ++i)
00412                 V(i) = NULL;
00413 }
00414 
00415  static long
00416 newiolabel(Void) {
00417         long rv;
00418         rv = ++lastiolabno;
00419         skiplabel = mklabel(rv);
00420         skiplabel->labdefined = 1;
00421         return rv;
00422         }
00423 
00424  void
00425 endioctl(Void)
00426 {
00427         int i;
00428         expptr p;
00429         struct io_setup *ios;
00430 
00431         inioctl = NO;
00432 
00433         /* set up for error recovery */
00434 
00435         ioerrlab = ioendlab = skiplab = jumplab = 0;
00436 
00437         if(p = V(IOSEND))
00438                 if(ISICON(p))
00439                         execlab(ioendlab = p->constblock.Const.ci);
00440                 else
00441                         err("bad end= clause");
00442 
00443         if(p = V(IOSERR))
00444                 if(ISICON(p))
00445                         execlab(ioerrlab = p->constblock.Const.ci);
00446                 else
00447                         err("bad err= clause");
00448 
00449         if(IOSTP)
00450                 if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
00451                 {
00452                         err("iostat must be an integer variable");
00453                         frexpr(IOSTP);
00454                         IOSTP = NULL;
00455                 }
00456 
00457         if(iostmt == IOREAD)
00458         {
00459                 if(IOSTP)
00460                 {
00461                         if(ioerrlab && ioendlab && ioerrlab==ioendlab)
00462                                 jumplab = ioerrlab;
00463                         else
00464                                 skiplab = jumplab = newiolabel();
00465                 }
00466                 else    {
00467                         if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
00468                         {
00469                                 IOSTP = (expptr) mktmp(TYINT, ENULL);
00470                                 skiplab = jumplab = newiolabel();
00471                         }
00472                         else
00473                                 jumplab = (ioerrlab ? ioerrlab : ioendlab);
00474                 }
00475         }
00476         else if(iostmt == IOWRITE)
00477         {
00478                 if(IOSTP && !ioerrlab)
00479                         skiplab = jumplab = newiolabel();
00480                 else
00481                         jumplab = ioerrlab;
00482         }
00483         else
00484                 jumplab = ioerrlab;
00485 
00486         endbit = IOSTP!=NULL || ioendlab!=0;    /* for use in startrw() */
00487         errbit = IOSTP!=NULL || ioerrlab!=0;
00488         if (jumplab && !IOSTP)
00489                 IOSTP = (expptr) mktmp(TYINT, ENULL);
00490 
00491         if(iostmt!=IOREAD && iostmt!=IOWRITE)
00492         {
00493                 ios = io_stuff + iostmt;
00494                 io_fields = ios->fields;
00495                 ioblkp = io_structs[iostmt];
00496                 if(ioblkp == NULL)
00497                         io_structs[iostmt] = ioblkp =
00498                                 autovar(1, ios->type, ENULL, "");
00499                 ioset(TYIOINT, XERR, ICON(errbit));
00500         }
00501 
00502         switch(iostmt)
00503         {
00504         case IOOPEN:
00505                 dofopen();
00506                 break;
00507 
00508         case IOCLOSE:
00509                 dofclose();
00510                 break;
00511 
00512         case IOINQUIRE:
00513                 dofinquire();
00514                 break;
00515 
00516         case IOBACKSPACE:
00517                 dofmove("f_back");
00518                 break;
00519 
00520         case IOREWIND:
00521                 dofmove("f_rew");
00522                 break;
00523 
00524         case IOENDFILE:
00525                 dofmove("f_end");
00526                 break;
00527 
00528         case IOREAD:
00529         case IOWRITE:
00530                 startrw();
00531                 break;
00532 
00533         default:
00534                 fatali("impossible iostmt %d", iostmt);
00535         }
00536         for(i = 1 ; i<=NIOS ; ++i)
00537                 if(i!=IOSIOSTAT && V(i)!=NULL)
00538                         frexpr(V(i));
00539 }
00540 
00541 
00542  int
00543 iocname(Void)
00544 {
00545         register int i;
00546         int found, mask;
00547 
00548         found = 0;
00549         mask = M(iostmt);
00550         for(i = 1 ; i <= NIOS ; ++i)
00551                 if(!strcmp(ioc[i].iocname, token))
00552                         if(ioc[i].iotype & mask)
00553                                 return(i);
00554                         else {
00555                                 found = i;
00556                                 break;
00557                                 }
00558         if(found) {
00559                 if (iostmt == IOOPEN && !strcmp(ioc[i].iocname, "name")) {
00560                         NOEXT("open with \"name=\" treated as \"file=\"");
00561                         for(i = 1; strcmp(ioc[i].iocname, "file"); i++);
00562                         return i;
00563                         }
00564                 errstr("invalid control %s for statement", ioc[found].iocname);
00565                 }
00566         else
00567                 errstr("unknown iocontrol %s", token);
00568         return(IOSBAD);
00569 }
00570 
00571 
00572  void
00573 #ifdef KR_headers
00574 ioclause(n, p)
00575         register int n;
00576         register expptr p;
00577 #else
00578 ioclause(register int n, register expptr p)
00579 #endif
00580 {
00581         struct Ioclist *iocp;
00582 
00583         ++nioctl;
00584         if(n == IOSBAD)
00585                 return;
00586         if(n == IOSPOSITIONAL)
00587                 {
00588                 n = nioctl;
00589                 if (n == IOSFMT) {
00590                         if (iostmt == IOOPEN) {
00591                                 n = IOSFILE;
00592                                 NOEXT("file= specifier omitted from open");
00593                                 }
00594                         else if (iostmt < IOREAD)
00595                                 goto illegal;
00596                         }
00597                 else if(n > IOSFMT)
00598                         {
00599  illegal:
00600                         err("illegal positional iocontrol");
00601                         return;
00602                         }
00603                 }
00604         else if (n == IOSNML)
00605                 n = IOSFMT;
00606 
00607         if(p == NULL)
00608         {
00609                 if(n == IOSUNIT)
00610                         p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
00611                 else if(n != IOSFMT)
00612                 {
00613                         err("illegal * iocontrol");
00614                         return;
00615                 }
00616         }
00617         if(n == IOSFMT)
00618                 ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
00619 
00620         iocp = & ioc[n];
00621         if(iocp->iocval == NULL)
00622         {
00623                 if(n!=IOSFMT && ( n!=IOSUNIT || (p && p->headblock.vtype!=TYCHAR) ) )
00624                         p = fixtype(p);
00625                 else if (p && p->tag == TPRIM
00626                            && p->primblock.namep->vclass == CLUNKNOWN) {
00627                         /* kludge made necessary by attempt to infer types
00628                          * for untyped external parameters: given an error
00629                          * in calling sequences, an integer argument might
00630                          * tentatively be assumed TYCHAR; this would otherwise
00631                          * be corrected too late in startrw after startrw
00632                          * had decided this to be an internal file.
00633                          */
00634                         vardcl(p->primblock.namep);
00635                         p->primblock.vtype = p->primblock.namep->vtype;
00636                         }
00637                 iocp->iocval = p;
00638         }
00639         else
00640                 errstr("iocontrol %s repeated", iocp->iocname);
00641 }
00642 
00643 /* io list item */
00644 
00645  void
00646 #ifdef KR_headers
00647 doio(list)
00648         chainp list;
00649 #else
00650 doio(chainp list)
00651 #endif
00652 {
00653         if(ioformatted == NAMEDIRECTED)
00654         {
00655                 if(list)
00656                         err("no I/O list allowed in NAMELIST read/write");
00657         }
00658         else
00659         {
00660                 doiolist(list);
00661                 ioroutine[0] = 'e';
00662                 if (skiplab)
00663                         jumplab = 0;
00664                 putiocall( call0(TYINT, ioroutine) );
00665         }
00666 }
00667 
00668 
00669 
00670 
00671 
00672  LOCAL void
00673 #ifdef KR_headers
00674 doiolist(p0)
00675         chainp p0;
00676 #else
00677 doiolist(chainp p0)
00678 #endif
00679 {
00680         chainp p;
00681         register tagptr q;
00682         register expptr qe;
00683         register Namep qn;
00684         Addrp tp;
00685         int range;
00686         extern char *ohalign;
00687 
00688         for (p = p0 ; p ; p = p->nextp)
00689         {
00690                 q = (tagptr)p->datap;
00691                 if(q->tag == TIMPLDO)
00692                 {
00693                         exdo(range = (int)newlabel(), (Namep)0,
00694                                 q->impldoblock.impdospec);
00695                         doiolist(q->impldoblock.datalist);
00696                         enddo(range);
00697                         free( (charptr) q);
00698                 }
00699                 else    {
00700                         if(q->tag==TPRIM && q->primblock.argsp==NULL
00701                             && q->primblock.namep->vdim!=NULL)
00702                         {
00703                                 vardcl(qn = q->primblock.namep);
00704                                 if(qn->vdim->nelt) {
00705                                         putio( fixtype(cpexpr(qn->vdim->nelt)),
00706                                             (expptr)mkscalar(qn) );
00707                                         qn->vlastdim = 0;
00708                                         }
00709                                 else
00710                                         err("attempt to i/o array of unknown size");
00711                         }
00712                         else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
00713                             (qe = (expptr) memversion(q->primblock.namep)) )
00714                                 putio(ICON(1),qe);
00715                         else if (ISCONST(q) && q->constblock.vtype == TYCHAR) {
00716                                 halign = 0;
00717                                 putio(ICON(1), qe = fixtype(cpexpr(q)));
00718                                 halign = ohalign;
00719                                 }
00720                         else if(((qe = fixtype(cpexpr(q)))->tag==TADDR &&
00721                             (qe->addrblock.uname_tag != UNAM_CONST ||
00722                             !ISCOMPLEX(qe -> addrblock.vtype))) ||
00723                             (qe -> tag == TCONST && !ISCOMPLEX(qe ->
00724                             headblock.vtype))) {
00725                                 if (qe -> tag == TCONST)
00726                                         qe = (expptr) putconst((Constp)qe);
00727                                 putio(ICON(1), qe);
00728                         }
00729                         else if(qe->headblock.vtype != TYERROR)
00730                         {
00731                                 if(iostmt == IOWRITE)
00732                                 {
00733                                         expptr qvl;
00734                                         qvl = NULL;
00735                                         if( ISCHAR(qe) )
00736                                         {
00737                                                 qvl = (expptr)
00738                                                     cpexpr(qe->headblock.vleng);
00739                                                 tp = mktmp(qe->headblock.vtype,
00740                                                     ICON(lencat(qe)));
00741                                         }
00742                                         else
00743                                                 tp = mktmp(qe->headblock.vtype,
00744                                                     qe->headblock.vleng);
00745                                         puteq( cpexpr((expptr)tp), qe);
00746                                         if(qvl) /* put right length on block */
00747                                         {
00748                                                 frexpr(tp->vleng);
00749                                                 tp->vleng = qvl;
00750                                         }
00751                                         putio(ICON(1), (expptr)tp);
00752                                 }
00753                                 else
00754                                         err("non-left side in READ list");
00755                         }
00756                         frexpr(q);
00757                 }
00758         }
00759         frchain( &p0 );
00760 }
00761 
00762  int iocalladdr = TYADDR;       /* for fixing TYADDR in saveargtypes */
00763  int typeconv[TYERROR+1] = {
00764 #ifdef TYQUAD
00765                 0, 1, 11, 2, 3, 14, 4, 5, 6, 7, 12, 13, 8, 9, 10, 15
00766 #else
00767                 0, 1, 11, 2, 3,     4, 5, 6, 7, 12, 13, 8, 9, 10, 14
00768 #endif
00769                 };
00770 
00771  LOCAL void
00772 #ifdef KR_headers
00773 putio(nelt, addr)
00774         expptr nelt;
00775         register expptr addr;
00776 #else
00777 putio(expptr nelt, register expptr addr)
00778 #endif
00779 {
00780         int type;
00781         register expptr q;
00782         register Addrp c = 0;
00783 
00784         type = addr->headblock.vtype;
00785         if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
00786         {
00787                 nelt = mkexpr(OPSTAR, ICON(2), nelt);
00788                 type -= (TYCOMPLEX-TYREAL);
00789         }
00790 
00791         /* pass a length with every item.  for noncharacter data, fake one */
00792         if(type != TYCHAR)
00793         {
00794 
00795                 if( ISCONST(addr) )
00796                         addr = (expptr) putconst((Constp)addr);
00797                 c = ALLOC(Addrblock);
00798                 c->tag = TADDR;
00799                 c->vtype = TYLENG;
00800                 c->vstg = STGAUTO;
00801                 c->ntempelt = 1;
00802                 c->isarray = 1;
00803                 c->memoffset = ICON(0);
00804                 c->uname_tag = UNAM_IDENT;
00805                 c->charleng = 1;
00806                 sprintf(c->user.ident, "(ftnlen)sizeof(%s)", Typename[type]);
00807                 addr = mkexpr(OPCHARCAST, addr, ENULL);
00808                 }
00809 
00810         nelt = fixtype( mkconv(tyioint,nelt) );
00811         if(ioformatted == LISTDIRECTED) {
00812                 expptr mc = mkconv(tyioint, ICON(typeconv[type]));
00813                 q = c   ? call4(TYINT, "do_lio", mc, nelt, addr, (expptr)c)
00814                         : call3(TYINT, "do_lio", mc, nelt, addr);
00815                 }
00816         else {
00817                 char *s = (char*)(ioformatted==FORMATTED ? "do_fio"
00818                         : !byterev ? "do_uio"
00819                         : ONEOF(type, M(TYCHAR)|M(TYINT1)|M(TYLOGICAL1))
00820                         ? "do_ucio" : "do_unio");
00821                 q = c   ? call3(TYINT, s, nelt, addr, (expptr)c)
00822                         : call2(TYINT, s, nelt, addr);
00823                 }
00824         iocalladdr = TYCHAR;
00825         putiocall(q);
00826         iocalladdr = TYADDR;
00827 }
00828 
00829 
00830 
00831  void
00832 endio(Void)
00833 {
00834         if(skiplab)
00835         {
00836                 if (ioformatted != NAMEDIRECTED)
00837                         p1_label((long)(skiplabel - labeltab));
00838                 if(ioendlab) {
00839                         exif( mkexpr(OPLT, cpexpr(IOSTP), ICON(0)));
00840                         exgoto(execlab(ioendlab));
00841                         exendif();
00842                         }
00843                 if(ioerrlab) {
00844                         exif( mkexpr(iostmt==IOREAD||iostmt==IOWRITE
00845                                         ? OPGT : OPNE,
00846                                 cpexpr(IOSTP), ICON(0)));
00847                         exgoto(execlab(ioerrlab));
00848                         exendif();
00849                         }
00850         }
00851 
00852         if(IOSTP)
00853                 frexpr(IOSTP);
00854 }
00855 
00856 
00857 
00858  LOCAL void
00859 #ifdef KR_headers
00860 putiocall(q)
00861         register expptr q;
00862 #else
00863 putiocall(register expptr q)
00864 #endif
00865 {
00866         int tyintsave;
00867 
00868         tyintsave = tyint;
00869         tyint = tyioint;        /* for -I2 and -i2 */
00870 
00871         if(IOSTP)
00872         {
00873                 q->headblock.vtype = TYINT;
00874                 q = fixexpr((Exprp)mkexpr(OPASSIGN, cpexpr(IOSTP), q));
00875         }
00876         putexpr(q);
00877         if(jumplab) {
00878                 exif(mkexpr(OPNE, cpexpr(IOSTP), ICON(0)));
00879                 exgoto(execlab(jumplab));
00880                 exendif();
00881                 }
00882         tyint = tyintsave;
00883 }
00884 
00885  void
00886 #ifdef KR_headers
00887 fmtname(np, q)
00888         Namep np;
00889         register Addrp q;
00890 #else
00891 fmtname(Namep np, register Addrp q)
00892 #endif
00893 {
00894         register int k;
00895         register char *s, *t;
00896         extern chainp assigned_fmts;
00897 
00898         if (!np->vfmt_asg) {
00899                 np->vfmt_asg = 1;
00900                 assigned_fmts = mkchain((char *)np, assigned_fmts);
00901                 }
00902         k = strlen(s = np->fvarname);
00903         if (k < IDENT_LEN - 4) {
00904                 q->uname_tag = UNAM_IDENT;
00905                 t = q->user.ident;
00906                 }
00907         else {
00908                 q->uname_tag = UNAM_CHARP;
00909                 q->user.Charp = t = mem(k + 5,0);
00910                 }
00911         sprintf(t, "%s_fmt", s);
00912         }
00913 
00914  LOCAL Addrp
00915 #ifdef KR_headers
00916 asg_addr(p)
00917         union Expression *p;
00918 #else
00919 asg_addr(union Expression *p)
00920 #endif
00921 {
00922         register Addrp q;
00923 
00924         if (p->tag != TPRIM)
00925                 badtag("asg_addr", p->tag);
00926         q = ALLOC(Addrblock);
00927         q->tag = TADDR;
00928         q->vtype = TYCHAR;
00929         q->vstg = STGAUTO;
00930         q->ntempelt = 1;
00931         q->isarray = 0;
00932         q->memoffset = ICON(0);
00933         fmtname(p->primblock.namep, q);
00934         return q;
00935         }
00936 
00937  void
00938 startrw(Void)
00939 {
00940         register expptr p;
00941         register Namep np;
00942         register Addrp unitp, fmtp, recp;
00943         register expptr nump;
00944         int iostmt1;
00945         flag intfile, sequential, ok, varfmt;
00946         struct io_setup *ios;
00947 
00948         /* First look at all the parameters and determine what is to be done */
00949 
00950         ok = YES;
00951         statstruct = YES;
00952 
00953         intfile = NO;
00954         if(p = V(IOSUNIT))
00955         {
00956                 if( ISINT(p->headblock.vtype) ) {
00957  int_unit:
00958                         unitp = (Addrp) cpexpr(p);
00959                         }
00960                 else if(p->headblock.vtype == TYCHAR)
00961                 {
00962                         if (nioctl == 1 && iostmt == IOREAD) {
00963                                 /* kludge to recognize READ(format expr) */
00964                                 V(IOSFMT) = p;
00965                                 V(IOSUNIT) = p = (expptr) IOSTDIN;
00966                                 ioformatted = FORMATTED;
00967                                 goto int_unit;
00968                                 }
00969                         intfile = YES;
00970                         if(p->tag==TPRIM && p->primblock.argsp==NULL &&
00971                             (np = p->primblock.namep)->vdim!=NULL)
00972                         {
00973                                 vardcl(np);
00974                                 if(nump = np->vdim->nelt)
00975                                 {
00976                                         nump = fixtype(cpexpr(nump));
00977                                         if( ! ISCONST(nump) ) {
00978                                                 statstruct = NO;
00979                                                 np->vlastdim = 0;
00980                                                 }
00981                                 }
00982                                 else
00983                                 {
00984                                         err("attempt to use internal unit array of unknown size");
00985                                         ok = NO;
00986                                         nump = ICON(1);
00987                                 }
00988                                 unitp = mkscalar(np);
00989                         }
00990                         else    {
00991                                 nump = ICON(1);
00992                                 unitp = (Addrp /*pjw */) fixtype(cpexpr(p));
00993                         }
00994                         if(! isstatic((expptr)unitp) )
00995                                 statstruct = NO;
00996                 }
00997                 else {
00998                         err("unit specifier not of type integer or character");
00999                         ok = NO;
01000                         }
01001         }
01002         else
01003         {
01004                 err("bad unit specifier");
01005                 ok = NO;
01006         }
01007 
01008         sequential = YES;
01009         if(p = V(IOSREC))
01010                 if( ISINT(p->headblock.vtype) )
01011                 {
01012                         recp = (Addrp) cpexpr(p);
01013                         sequential = NO;
01014                 }
01015                 else    {
01016                         err("bad REC= clause");
01017                         ok = NO;
01018                 }
01019         else
01020                 recp = NULL;
01021 
01022 
01023         varfmt = YES;
01024         fmtp = NULL;
01025         if(p = V(IOSFMT))
01026         {
01027                 if(p->tag==TPRIM && p->primblock.argsp==NULL)
01028                 {
01029                         np = p->primblock.namep;
01030                         if(np->vclass == CLNAMELIST)
01031                         {
01032                                 ioformatted = NAMEDIRECTED;
01033                                 fmtp = (Addrp) fixtype(p);
01034                                 V(IOSFMT) = (expptr)fmtp;
01035                                 if (skiplab)
01036                                         jumplab = 0;
01037                                 goto endfmt;
01038                         }
01039                         vardcl(np);
01040                         if(np->vdim)
01041                         {
01042                                 if( ! ONEOF(np->vstg, MSKSTATIC) )
01043                                         statstruct = NO;
01044                                 fmtp = mkscalar(np);
01045                                 goto endfmt;
01046                         }
01047                         if( ISINT(np->vtype) )  /* ASSIGNed label */
01048                         {
01049                                 statstruct = NO;
01050                                 varfmt = YES;
01051                                 fmtp = asg_addr(p);
01052                                 goto endfmt;
01053                         }
01054                 }
01055                 p = V(IOSFMT) = fixtype(p);
01056                 if(p->headblock.vtype == TYCHAR
01057                         /* Since we allow write(6,n)            */
01058                         /* we may as well allow write(6,n(2))   */
01059                 || p->tag == TADDR && ISINT(p->addrblock.vtype))
01060                 {
01061                         if( ! isstatic(p) )
01062                                 statstruct = NO;
01063                         fmtp = (Addrp) cpexpr(p);
01064                 }
01065                 else if( ISICON(p) )
01066                 {
01067                         struct Labelblock *lp;
01068                         lp = mklabel(p->constblock.Const.ci);
01069                         if (fmtstmt(lp) > 0)
01070                         {
01071                                 fmtp = (Addrp)mkaddcon(lp->stateno);
01072                                 /* lp->stateno for names fmt_nnn */
01073                                 lp->fmtlabused = 1;
01074                                 varfmt = NO;
01075                         }
01076                         else
01077                                 ioformatted = UNFORMATTED;
01078                 }
01079                 else    {
01080                         err("bad format descriptor");
01081                         ioformatted = UNFORMATTED;
01082                         ok = NO;
01083                 }
01084         }
01085         else
01086                 fmtp = NULL;
01087 
01088 endfmt:
01089         if(intfile) {
01090                 if (ioformatted==UNFORMATTED) {
01091                         err("unformatted internal I/O not allowed");
01092                         ok = NO;
01093                         }
01094                 if (recp) {
01095                         err("direct internal I/O not allowed");
01096                         ok = NO;
01097                         }
01098                 }
01099         if(!sequential && ioformatted==LISTDIRECTED)
01100         {
01101                 err("direct list-directed I/O not allowed");
01102                 ok = NO;
01103         }
01104         if(!sequential && ioformatted==NAMEDIRECTED)
01105         {
01106                 err("direct namelist I/O not allowed");
01107                 ok = NO;
01108         }
01109 
01110         if( ! ok ) {
01111                 statstruct = NO;
01112                 return;
01113                 }
01114 
01115         /*
01116    Now put out the I/O structure, statically if all the clauses
01117    are constants, dynamically otherwise
01118 */
01119 
01120         if (intfile) {
01121                 ios = io_stuff + iostmt;
01122                 iostmt1 = IOREAD;
01123                 }
01124         else {
01125                 ios = io_stuff;
01126                 iostmt1 = 0;
01127                 }
01128         io_fields = ios->fields;
01129         if(statstruct)
01130         {
01131                 ioblkp = ALLOC(Addrblock);
01132                 ioblkp->tag = TADDR;
01133                 ioblkp->vtype = ios->type;
01134                 ioblkp->vclass = CLVAR;
01135                 ioblkp->vstg = STGINIT;
01136                 ioblkp->memno = ++lastvarno;
01137                 ioblkp->memoffset = ICON(0);
01138                 ioblkp -> uname_tag = UNAM_IDENT;
01139                 new_iob_data(ios,
01140                         temp_name("io_", lastvarno, ioblkp->user.ident));                       }
01141         else if(!(ioblkp = io_structs[iostmt1]))
01142                 io_structs[iostmt1] = ioblkp =
01143                         autovar(1, ios->type, ENULL, "");
01144 
01145         ioset(TYIOINT, XERR, ICON(errbit));
01146         if(iostmt == IOREAD)
01147                 ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
01148 
01149         if(intfile)
01150         {
01151                 ioset(TYIOINT, XIRNUM, nump);
01152                 ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
01153                 ioseta(XIUNIT, unitp);
01154         }
01155         else
01156                 ioset(TYIOINT, XUNIT, (expptr) unitp);
01157 
01158         if(recp)
01159                 ioset(TYIOINT, /* intfile ? XIREC : */ XREC, (expptr) recp);
01160 
01161         if(varfmt)
01162                 ioseta( intfile ? XIFMT : XFMT , fmtp);
01163         else
01164                 ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
01165 
01166         ioroutine[0] = 's';
01167         ioroutine[1] = '_';
01168         ioroutine[2] = iostmt==IOREAD ? 'r' : 'w';
01169         ioroutine[3] = "ds"[sequential];
01170         ioroutine[4] = "ufln"[ioformatted];
01171         ioroutine[5] = "ei"[intfile];
01172         ioroutine[6] = '\0';
01173 
01174         putiocall( call1(TYINT, ioroutine, cpexpr((expptr)ioblkp) ));
01175 
01176         if(statstruct)
01177         {
01178                 frexpr((expptr)ioblkp);
01179                 statstruct = NO;
01180                 ioblkp = 0;     /* unnecessary */
01181         }
01182 }
01183 
01184 
01185 
01186  LOCAL void
01187 dofopen(Void)
01188 {
01189         register expptr p;
01190 
01191         if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
01192                 ioset(TYIOINT, XUNIT, cpexpr(p) );
01193         else
01194                 err("bad unit in open");
01195         if( (p = V(IOSFILE)) )
01196                 if(p->headblock.vtype == TYCHAR)
01197                         ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
01198                 else
01199                         err("bad file in open");
01200 
01201         iosetc(XFNAME, p);
01202 
01203         if(p = V(IOSRECL))
01204                 if( ISINT(p->headblock.vtype) )
01205                         ioset(TYIOINT, XRECLEN, cpexpr(p) );
01206                 else
01207                         err("bad recl");
01208         else
01209                 ioset(TYIOINT, XRECLEN, ICON(0) );
01210 
01211         iosetc(XSTATUS, V(IOSSTATUS));
01212         iosetc(XACCESS, V(IOSACCESS));
01213         iosetc(XFORMATTED, V(IOSFORM));
01214         iosetc(XBLANK, V(IOSBLANK));
01215 
01216         putiocall( call1(TYINT, "f_open", cpexpr((expptr)ioblkp) ));
01217 }
01218 
01219 
01220  LOCAL void
01221 dofclose(Void)
01222 {
01223         register expptr p;
01224 
01225         if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
01226         {
01227                 ioset(TYIOINT, XUNIT, cpexpr(p) );
01228                 iosetc(XCLSTATUS, V(IOSSTATUS));
01229                 putiocall( call1(TYINT, "f_clos", cpexpr((expptr)ioblkp)) );
01230         }
01231         else
01232                 err("bad unit in close statement");
01233 }
01234 
01235 
01236  LOCAL void
01237 dofinquire(Void)
01238 {
01239         register expptr p;
01240         if(p = V(IOSUNIT))
01241         {
01242                 if( V(IOSFILE) )
01243                         err("inquire by unit or by file, not both");
01244                 ioset(TYIOINT, XUNIT, cpexpr(p) );
01245         }
01246         else if( ! V(IOSFILE) )
01247                 err("must inquire by unit or by file");
01248         iosetlc(IOSFILE, XFILE, XFILELEN);
01249         iosetip(IOSEXISTS, XEXISTS);
01250         iosetip(IOSOPENED, XOPEN);
01251         iosetip(IOSNUMBER, XNUMBER);
01252         iosetip(IOSNAMED, XNAMED);
01253         iosetlc(IOSNAME, XNAME, XNAMELEN);
01254         iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
01255         iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
01256         iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
01257         iosetlc(IOSFORM, XFORM, XFORMLEN);
01258         iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
01259         iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
01260         iosetip(IOSRECL, XQRECL);
01261         iosetip(IOSNEXTREC, XNEXTREC);
01262         iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
01263 
01264         putiocall( call1(TYINT,  "f_inqu", cpexpr((expptr)ioblkp) ));
01265 }
01266 
01267 
01268 
01269  LOCAL void
01270 #ifdef KR_headers
01271 dofmove(subname)
01272         char *subname;
01273 #else
01274 dofmove(char *subname)
01275 #endif
01276 {
01277         register expptr p;
01278 
01279         if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
01280         {
01281                 ioset(TYIOINT, XUNIT, cpexpr(p) );
01282                 putiocall( call1(TYINT, subname, cpexpr((expptr)ioblkp) ));
01283         }
01284         else
01285                 err("bad unit in I/O motion statement");
01286 }
01287 
01288 static int ioset_assign = OPASSIGN;
01289 
01290  LOCAL void
01291 #ifdef KR_headers
01292 ioset(type, offset, p)
01293         int type;
01294         int offset;
01295         register expptr p;
01296 #else
01297 ioset(int type, int offset, register expptr p)
01298 #endif
01299 {
01300         offset /= SZLONG;
01301         if(statstruct && ISCONST(p)) {
01302                 register char *s;
01303                 switch(type) {
01304                         case TYADDR:    /* stmt label */
01305                                 s = "fmt_";
01306                                 break;
01307                         case TYIOINT:
01308                                 s = "";
01309                                 break;
01310                         default:
01311                                 badtype("ioset", type);
01312                         }
01313                 iob_list->fields[offset] =
01314                         string_num(s, p->constblock.Const.ci);
01315                 frexpr(p);
01316                 }
01317         else {
01318                 register Addrp q;
01319 
01320                 q = ALLOC(Addrblock);
01321                 q->tag = TADDR;
01322                 q->vtype = type;
01323                 q->vstg = STGAUTO;
01324                 q->ntempelt = 1;
01325                 q->isarray = 0;
01326                 q->memoffset = ICON(0);
01327                 q->uname_tag = UNAM_IDENT;
01328                 sprintf(q->user.ident, "%s.%s",
01329                         statstruct ? iob_list->name : ioblkp->user.ident,
01330                         io_fields[offset + 1]);
01331                 if (type == TYADDR && p->tag == TCONST
01332                                    && p->constblock.vtype == TYADDR) {
01333                         /* kludge */
01334                         register Addrp p1;
01335                         p1 = ALLOC(Addrblock);
01336                         p1->tag = TADDR;
01337                         p1->vtype = type;
01338                         p1->vstg = STGAUTO;     /* wrong, but who cares? */
01339                         p1->ntempelt = 1;
01340                         p1->isarray = 0;
01341                         p1->memoffset = ICON(0);
01342                         p1->uname_tag = UNAM_IDENT;
01343                         sprintf(p1->user.ident, "fmt_%ld",
01344                                 p->constblock.Const.ci);
01345                         frexpr(p);
01346                         p = (expptr)p1;
01347                         }
01348                 if (type == TYADDR && p->headblock.vtype == TYCHAR)
01349                         q->vtype = TYCHAR;
01350                 putexpr(mkexpr(ioset_assign, (expptr)q, p));
01351                 }
01352 }
01353 
01354 
01355 
01356 
01357  LOCAL void
01358 #ifdef KR_headers
01359 iosetc(offset, p)
01360         int offset;
01361         register expptr p;
01362 #else
01363 iosetc(int offset, register expptr p)
01364 #endif
01365 {
01366         if(p == NULL)
01367                 ioset(TYADDR, offset, ICON(0) );
01368         else if(p->headblock.vtype == TYCHAR) {
01369                 p = putx(fixtype((expptr)putchop(cpexpr(p))));
01370                 ioset(TYADDR, offset, addrof(p));
01371                 }
01372         else
01373                 err("non-character control clause");
01374 }
01375 
01376 
01377 
01378  LOCAL void
01379 #ifdef KR_headers
01380 ioseta(offset, p)
01381         int offset;
01382         register Addrp p;
01383 #else
01384 ioseta(int offset, register Addrp p)
01385 #endif
01386 {
01387         char *s, *s1;
01388         static char who[] = "ioseta";
01389         expptr e, mo;
01390         Namep np;
01391         ftnint ci;
01392         int k;
01393         char buf[24], buf1[24];
01394         Extsym *comm;
01395         extern int usedefsforcommon;
01396 
01397         if(statstruct)
01398         {
01399                 if (!p)
01400                         return;
01401                 if (p->tag != TADDR)
01402                         badtag(who, p->tag);
01403                 offset /= SZLONG;
01404                 switch(p->uname_tag) {
01405                     case UNAM_NAME:
01406                         mo = p->memoffset;
01407                         if (mo->tag != TCONST)
01408                                 badtag("ioseta/memoffset", mo->tag);
01409                         np = p->user.name;
01410                         np->visused = 1;
01411                         ci = mo->constblock.Const.ci - np->voffset;
01412                         if (np->vstg == STGCOMMON
01413                         && !np->vcommequiv
01414                         && !usedefsforcommon) {
01415                                 comm = &extsymtab[np->vardesc.varno];
01416                                 sprintf(buf, "%d.", comm->curno);
01417                                 k = strlen(buf) + strlen(comm->cextname)
01418                                         + strlen(np->cvarname);
01419                                 if (ci) {
01420                                         sprintf(buf1, "+%ld", ci);
01421                                         k += strlen(buf1);
01422                                         }
01423                                 else
01424                                         buf1[0] = 0;
01425                                 s = mem(k + 1, 0);
01426                                 sprintf(s, "%s%s%s%s", comm->cextname, buf,
01427                                         np->cvarname, buf1);
01428                                 }
01429                         else if (ci) {
01430                                 sprintf(buf,"%ld", ci);
01431                                 s1 = p->user.name->cvarname;
01432                                 k = strlen(buf) + strlen(s1);
01433                                 sprintf(s = mem(k+2,0), "%s+%s", s1, buf);
01434                                 }
01435                         else
01436                                 s = cpstring(np->cvarname);
01437                         break;
01438                     case UNAM_CONST:
01439                         s = tostring(p->user.Const.ccp1.ccp0,
01440                                 (int)p->vleng->constblock.Const.ci);
01441                         break;
01442                     default:
01443                         badthing("uname_tag", who, p->uname_tag);
01444                     }
01445                 /* kludge for Hollerith */
01446                 if (p->vtype != TYCHAR) {
01447                         s1 = mem(strlen(s)+10,0);
01448                         sprintf(s1, "(char *)%s%s", p->isarray ? "" : "&", s);
01449                         s = s1;
01450                         }
01451                 iob_list->fields[offset] = s;
01452         }
01453         else {
01454                 if (!p)
01455                         e = ICON(0);
01456                 else if (p->vtype != TYCHAR) {
01457                         NOEXT("non-character variable as format or internal unit");
01458                         e = mkexpr(OPCHARCAST, (expptr)p, ENULL);
01459                         }
01460                 else
01461                         e = addrof((expptr)p);
01462                 ioset(TYADDR, offset, e);
01463                 }
01464 }
01465 
01466 
01467 
01468 
01469  LOCAL void
01470 #ifdef KR_headers
01471 iosetip(i, offset)
01472         int i;
01473         int offset;
01474 #else
01475 iosetip(int i, int offset)
01476 #endif
01477 {
01478         register expptr p;
01479 
01480         if(p = V(i))
01481                 if(p->tag==TADDR &&
01482                     ONEOF(p->addrblock.vtype, inqmask) ) {
01483                         ioset_assign = OPASSIGNI;
01484                         ioset(TYADDR, offset, addrof(cpexpr(p)) );
01485                         ioset_assign = OPASSIGN;
01486                         }
01487                 else
01488                         errstr("impossible inquire parameter %s", ioc[i].iocname);
01489         else
01490                 ioset(TYADDR, offset, ICON(0) );
01491 }
01492 
01493 
01494 
01495  LOCAL void
01496 #ifdef KR_headers
01497 iosetlc(i, offp, offl)
01498         int i;
01499         int offp;
01500         int offl;
01501 #else
01502 iosetlc(int i, int offp, int offl)
01503 #endif
01504 {
01505         register expptr p;
01506         if( (p = V(i)) && p->headblock.vtype==TYCHAR)
01507                 ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );
01508         iosetc(offp, p);
01509 }

Generated on Sun Mar 4 15:03:44 2007 for Scilab [trunk] by  doxygen 1.5.1