|
|
1.1 ! root 1: /* @(#)nio.c 1.1 */ ! 2: #include <stdio.h> ! 3: #include <ctype.h> ! 4: #include "fio.h" ! 5: #include "fmt.h" ! 6: #include "lio.h" ! 7: ! 8: /* ! 9: * namelist io ! 10: * ! 11: * see f77's proc.c at namelist() for description ! 12: */ ! 13: ! 14: typedef struct { ! 15: int ndims; /* # of dimensions */ ! 16: int nels; /* # of elements */ ! 17: int baseoff; /* how to get to (0,...,0) element */ ! 18: int span[7]; /* span of each dimension +1+ */ ! 19: } Dims; /* dimension descriptor */ ! 20: ! 21: ! 22: /* +1+ note: only # of dimensions ! 23: applies here, i.e. actual array ! 24: is between 0 and 7 elements based ! 25: on ndims */ ! 26: ! 27: typedef union { ! 28: char *pchar; ! 29: short *pshort; ! 30: int *pint; ! 31: long *plong; ! 32: float *pfloat; ! 33: double *pdouble; ! 34: char **pptr; ! 35: } Pointer; /* pointer to all sorts of things */ ! 36: ! 37: ! 38: typedef struct { ! 39: char varname[18]; /* name of variable */ ! 40: Pointer varaddr; /* where it is */ ! 41: int type; /* its type */ ! 42: Dims *dimp; /* dimension descriptor */ ! 43: } Nlentry; /* namelist entry: 1 for each var */ ! 44: ! 45: ! 46: typedef struct { ! 47: char nlname[18]; /* name of namelist */ ! 48: Nlentry nlvnames[1]; /* array of variable descriptors +2+*/ ! 49: } Namelist; ! 50: ! 51: /* +2+ note: this array is not bounded ! 52: but is terminated by an entry with a ! 53: null varname */ ! 54: ! 55: /* ! 56: * s_rsne - start read namelist external ! 57: * ! 58: * s_rsne ! 59: * if (file not initialized) ! 60: * intialize it ! 61: * if (file doesn't jive with namelist io) ! 62: * return error ! 63: * initialize some global variables ! 64: * if (not currently reading on file OR not capable of doing so) ! 65: * return error ! 66: * read namelist name ! 67: * if (not correct namelist name) ! 68: * error ! 69: * determine number of variables in namelist ! 70: * read variable name ! 71: * while (variable name is not "&end") ! 72: * if (variable is in namelist) ! 73: * read value(s) for it ! 74: * else ! 75: * error ! 76: * if (not correct number of variables read) ! 77: * error ! 78: * end s_rsne ! 79: */ ! 80: ! 81: #define BSIZ 50 ! 82: ! 83: static char nlrs[] = "namelist read"; ! 84: ! 85: s_rsne(pnlarg) ! 86: cilist *pnlarg; ! 87: { ! 88: Namelist *pnl; ! 89: Nlentry *pnlent, *findit(); ! 90: int nvars, n; ! 91: char buf[BSIZ], *getword(); ! 92: ! 93: if (!init) ! 94: f_init(); ! 95: if (n = c_nle(pnlarg)) ! 96: return (n); ! 97: reading = external = sequential = 1; ! 98: formatted = 0; ! 99: if (curunit->uwrt && nowreading(curunit)) ! 100: return (1); ! 101: pnl = (Namelist *) pnlarg->cifmt; ! 102: if (getc(cf) != ' ' || getc(cf) != '&') ! 103: err(pnlarg->cierr, 115, nlrs); ! 104: if (strcmp(pnl->nlname, getword(buf, strlen(pnl->nlname)))) ! 105: err(pnlarg->cierr, 118, buf); ! 106: n = getc(cf); ! 107: if (!isspace(n)) ! 108: err(pnlarg->cierr, 115, nlrs); ! 109: for (nvars=0, pnlent = pnl->nlvnames; strlen(pnlent->varname); ++pnlent) ! 110: ++nvars; ! 111: n = 0; ! 112: elist = pnlarg; ! 113: while (nvars--) ! 114: { ! 115: if (!getword(buf, BSIZ - 1)) ! 116: err(pnlarg->cierr, 120, nlrs); ! 117: if (!strcmp(buf, "&end")) ! 118: err(pnlarg->cierr, 121, nlrs); ! 119: if (!(pnlent = findit(buf, pnl->nlvnames))) ! 120: err(pnlarg->cierr, 119, buf); ! 121: if (getvar(pnlent)) ! 122: err(pnlarg->cierr, 120, nlrs); ! 123: } ! 124: if (!getword(buf, BSIZ - 1)) ! 125: err(pnlarg->cierr, 120, nlrs); ! 126: if (strcmp(buf, "&end")) ! 127: err(pnlarg->cierr, 121, nlrs); ! 128: return (0); ! 129: } ! 130: ! 131: /* miscellaneous utility functions for namelist read */ ! 132: ! 133: /* getword - get a "word" text string from current file */ ! 134: ! 135: char *getword(s, n) ! 136: char *s; ! 137: int n; ! 138: { ! 139: int i; ! 140: char *p; ! 141: ! 142: p = s; ! 143: i = getc(cf); ! 144: while (isspace(i) || (ispunct(i) && i != '&')) ! 145: i = getc(cf); ! 146: while (n--) ! 147: { ! 148: if (i != EOF && i != '=' && !isspace(i)) ! 149: if (isupper(i)) ! 150: *p++ = tolower(i); ! 151: else ! 152: *p++ = i; ! 153: else ! 154: break; ! 155: i = getc(cf); ! 156: } ! 157: if (feof(cf) && p == s) ! 158: return (NULL); ! 159: *p = '\0'; ! 160: return (s); ! 161: } ! 162: ! 163: /* findit - find key in list of Nlentrys */ ! 164: ! 165: Nlentry *findit(key, list) ! 166: char *key; ! 167: Nlentry *list; ! 168: { ! 169: while (strlen(list->varname)) ! 170: { ! 171: if (!strcmp(key, list->varname)) ! 172: return (list); ! 173: else ! 174: ++list; ! 175: } ! 176: return (NULL); ! 177: } ! 178: ! 179: /* getvar - read values for namelist io ! 180: * ! 181: * getvar uses l_read of list io to do all the dirty work, therefore ! 182: * it should be inserted into the library before lread.c (on UNIX ! 183: * systems with barbaric topologically sorted libraries) ! 184: * ! 185: * It sets the cierr flag so that l_read (and its subordinates) will ! 186: * not report errors, but pass them back so that the diagnostic message ! 187: * will appear to come from "namelist read". ! 188: */ ! 189: ! 190: getvar(pnlent) ! 191: Nlentry *pnlent; ! 192: { ! 193: int n, i, size; ! 194: ! 195: if (pnlent->dimp) ! 196: n = pnlent->dimp->nels; ! 197: else ! 198: n = 1; ! 199: elist->cierr = 1; ! 200: switch (pnlent->type) ! 201: { ! 202: case TYADDR: ! 203: size = sizeof(char *); ! 204: break; ! 205: case TYSHORT: ! 206: size = sizeof(short); ! 207: break; ! 208: case TYLOGICAL: ! 209: case TYLONG: ! 210: size = sizeof(long); ! 211: break; ! 212: case TYREAL: ! 213: case TYCOMPLEX: ! 214: size = sizeof(float); ! 215: break; ! 216: case TYDREAL: ! 217: case TYDCOMPLEX: ! 218: size = sizeof(double); ! 219: break; ! 220: default: ! 221: if (pnlent->type < 0) ! 222: { ! 223: if (n = l_read(&n, pnlent->varaddr, ! 224: -pnlent->type, TYCHAR)) ! 225: err(elist->cierr = 0, n, nlrs); ! 226: return (0); ! 227: } ! 228: else ! 229: err(elist->cierr = 0, 117, nlrs); ! 230: } ! 231: if (n = l_read(&n, pnlent->varaddr, size, pnlent->type)) ! 232: err(0, n, nlrs); ! 233: elist->cierr = 0; ! 234: return (0); ! 235: } ! 236: ! 237: /* ! 238: * s_wsne - start write namelist external ! 239: * ! 240: * s_wsne ! 241: * if (file not initialized) ! 242: * initialize it ! 243: * if (file doesn't jive with namelist io) ! 244: * return error ! 245: * initialize some global variables ! 246: * if (not currently writing on file OR not capable of doing so) ! 247: * return error ! 248: * set up namelist and entry pointers ! 249: * output namelist name in proper format ! 250: * do ! 251: * output variable name ! 252: * output value based on type ! 253: * point to next entry ! 254: * while (there are more to do AND sneakily output a comma separator ! 255: * output end line ! 256: * end s_wsne ! 257: */ ! 258: ! 259: s_wsne(pnlarg) ! 260: cilist *pnlarg; ! 261: { ! 262: Namelist *pnl; ! 263: Nlentry *pnlent; ! 264: Pointer ptr; ! 265: int i, n, vtype; ! 266: char *pch, buf[BSIZ]; ! 267: ! 268: if (!init) ! 269: f_init(); ! 270: if (n = c_nle(pnlarg)) ! 271: return(n); ! 272: reading = formatted = 0; ! 273: external = sequential = 1; ! 274: if (!curunit->uwrt && nowwriting(curunit)) ! 275: return(1); ! 276: pnl = (Namelist *) pnlarg->cifmt; ! 277: (void) putc(' ', cf); ! 278: (void) putc('&', cf); ! 279: (void) fputs(pnl->nlname, cf); ! 280: (void) putc('\n', cf); ! 281: (void) putc(' ', cf); ! 282: pnlent = pnl->nlvnames; ! 283: do { ! 284: (void) fputs(pnlent->varname, cf); ! 285: (void) putc('=', cf); ! 286: if (pnlent->dimp) ! 287: n = pnlent->dimp->nels; ! 288: else ! 289: n = 1; ! 290: if ((vtype = pnlent->type) < 0 && (pch = pnlent->varaddr.pchar)) ! 291: do { ! 292: (void) putc('\'', cf); ! 293: for (i = vtype; i; ++i) ! 294: (void) putc(*pch++, cf); ! 295: (void) putc('\'', cf); ! 296: } while (--n && !t_putc(',')); ! 297: else ! 298: { ! 299: ptr.pchar = pnlent->varaddr.pchar; ! 300: do { switch (vtype) ! 301: { ! 302: case TYADDR: ! 303: (void) sprintf(buf,"0x%x", *ptr.pptr++); ! 304: break; ! 305: case TYSHORT: ! 306: (void) sprintf(buf,"%d", *ptr.pshort++); ! 307: break; ! 308: case TYLONG: ! 309: (void) sprintf(buf,"%ld", *ptr.plong++); ! 310: break; ! 311: case TYREAL: ! 312: (void)sprintf(buf,"%.8f",*ptr.pfloat++); ! 313: break; ! 314: case TYDREAL: ! 315: (void) sprintf(buf, "%.18e", ! 316: *ptr.pdouble++); ! 317: break; ! 318: case TYCOMPLEX: ! 319: (void) sprintf(buf, "(%.8f,%.8f)", ! 320: *ptr.pfloat, *(ptr.pfloat+1)); ! 321: ptr.pfloat += 2; ! 322: break; ! 323: case TYDCOMPLEX: ! 324: (void) sprintf(buf, "(%.18e,%.18e)", ! 325: *ptr.pdouble, *(ptr.pdouble+1)); ! 326: ptr.pdouble += 2; ! 327: break; ! 328: case TYCHAR: ! 329: (void) sprintf(buf, "%c", *ptr.pchar++); ! 330: break; ! 331: case TYLOGICAL: ! 332: (void) sprintf(buf, ".%s.", ! 333: (*ptr.plong ? "TRUE" : "FALSE")); ! 334: break; ! 335: default: ! 336: err(pnlarg->cierr, 117, "namelist io"); ! 337: } ! 338: (void) fputs(buf, cf); ! 339: } while (--n && !t_putc(',')); ! 340: } ! 341: ++pnlent; ! 342: } while (strlen(pnlent->varname) && !t_putc(',')); ! 343: (void) fputs("\n &end\n", cf); ! 344: return (0); ! 345: } ! 346: ! 347: /* ! 348: * c_nle - check namelist external ! 349: * ! 350: * c_nle ! 351: * set up global variables ! 352: * if (bogus unit) ! 353: * fatal error ! 354: * if (unit is unitialized AND can't be) ! 355: * fatal error ! 356: * if (can't do unformatted io on unit) ! 357: * fatal error ! 358: * end c_nle ! 359: */ ! 360: ! 361: ! 362: c_nle(pcl) ! 363: cilist *pcl; ! 364: { ! 365: fmtbuf = "namelist io"; ! 366: if (0 > pcl->ciunit || pcl->ciunit >= MXUNIT) ! 367: err(pcl->cierr, 101, "start namelist io"); ! 368: scale = recpos = 0; ! 369: curunit = &units[pcl->ciunit]; ! 370: if (curunit->ufd == NULL && fk_open(SEQ, FMT, pcl->ciunit)) ! 371: err(pcl->cierr, 102, "namelist io"); ! 372: cf = curunit->ufd; ! 373: if (!curunit->ufmt) ! 374: err(pcl->cierr, 103, "namelist io"); ! 375: return(0); ! 376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.