148116Sbostic /*- 2*62213Sbostic * Copyright (c) 1980, 1993 3*62213Sbostic * The Regents of the University of California. All rights reserved. 448116Sbostic * 548116Sbostic * %sccs.include.redist.c% 622216Sdist */ 7766Speter 815934Smckusick #ifndef lint 9*62213Sbostic static char sccsid[] = "@(#)pcproc.c 8.1 (Berkeley) 06/06/93"; 1048116Sbostic #endif /* not lint */ 11766Speter 12766Speter #include "whoami.h" 13766Speter #ifdef PC 14766Speter /* 15766Speter * and to the end of the file 16766Speter */ 17766Speter #include "0.h" 18766Speter #include "tree.h" 1910372Speter #include "objfmt.h" 20766Speter #include "opcode.h" 2110372Speter #include "pc.h" 2218467Sralph #include <pcc.h> 2311333Speter #include "tmps.h" 2415934Smckusick #include "tree_ty.h" 25766Speter 26766Speter /* 2711883Smckusick * The constant EXPOSIZE specifies the number of digits in the exponent 2811883Smckusick * of real numbers. 2911883Smckusick * 309229Smckusick * The constant REALSPC defines the amount of forced padding preceeding 319229Smckusick * real numbers when they are printed. If REALSPC == 0, then no padding 329229Smckusick * is added, REALSPC == 1 adds one extra blank irregardless of the width 339229Smckusick * specified by the user. 349229Smckusick * 359229Smckusick * N.B. - Values greater than one require program mods. 369229Smckusick */ 3711883Smckusick #define EXPOSIZE 2 3811883Smckusick #define REALSPC 0 399229Smckusick 409229Smckusick /* 41766Speter * The following array is used to determine which classes may be read 42766Speter * from textfiles. It is indexed by the return value from classify. 43766Speter */ 44766Speter #define rdops(x) rdxxxx[(x)-(TFIRST)] 45766Speter 46766Speter int rdxxxx[] = { 47766Speter 0, /* -7 file types */ 48766Speter 0, /* -6 record types */ 49766Speter 0, /* -5 array types */ 50766Speter O_READE, /* -4 scalar types */ 51766Speter 0, /* -3 pointer types */ 52766Speter 0, /* -2 set types */ 53766Speter 0, /* -1 string types */ 54766Speter 0, /* 0 nil, no type */ 55766Speter O_READE, /* 1 boolean */ 56766Speter O_READC, /* 2 character */ 57766Speter O_READ4, /* 3 integer */ 58766Speter O_READ8 /* 4 real */ 59766Speter }; 60766Speter 61766Speter /* 62766Speter * Proc handles procedure calls. 63766Speter * Non-builtin procedures are "buck-passed" to func (with a flag 64766Speter * indicating that they are actually procedures. 65766Speter * builtin procedures are handled here. 66766Speter */ 67766Speter pcproc(r) 6815934Smckusick struct tnode *r; /* T_PCALL */ 69766Speter { 70766Speter register struct nl *p; 7115934Smckusick register struct tnode *alv, *al; 7215934Smckusick register op; 73766Speter struct nl *filetype, *ap; 7415934Smckusick int argc, typ, fmtspec, strfmt; 7515934Smckusick struct tnode *argv, *file; 767967Smckusick char fmt, format[20], *strptr, *cmd; 7715934Smckusick int prec, field, strnglen, fmtstart; 7815934Smckusick char *pu; 7915934Smckusick struct tnode *pua, *pui, *puz; 80766Speter int i, j, k; 81766Speter int itemwidth; 823833Speter char *readname; 833833Speter struct nl *tempnlp; 843833Speter long readtype; 853833Speter struct tmps soffset; 8615935Smckusick bool soffset_flag; 87766Speter 88766Speter #define CONPREC 4 89766Speter #define VARPREC 8 90766Speter #define CONWIDTH 1 91766Speter #define VARWIDTH 2 92766Speter #define SKIP 16 93766Speter 94766Speter /* 95766Speter * Verify that the name is 96766Speter * defined and is that of a 97766Speter * procedure. 98766Speter */ 9915934Smckusick p = lookup(r->pcall_node.proc_id); 10015934Smckusick if (p == NLNIL) { 10115934Smckusick rvlist(r->pcall_node.arg); 102766Speter return; 103766Speter } 1041197Speter if (p->class != PROC && p->class != FPROC) { 105766Speter error("Can't call %s, its %s not a procedure", p->symbol, classes[p->class]); 10615934Smckusick rvlist(r->pcall_node.arg); 107766Speter return; 108766Speter } 10915934Smckusick argv = r->pcall_node.arg; 110766Speter 111766Speter /* 112766Speter * Call handles user defined 113766Speter * procedures and functions. 114766Speter */ 115766Speter if (bn != 0) { 11615934Smckusick (void) call(p, argv, PROC, bn); 117766Speter return; 118766Speter } 119766Speter 120766Speter /* 121766Speter * Call to built-in procedure. 122766Speter * Count the arguments. 123766Speter */ 124766Speter argc = 0; 12515934Smckusick for (al = argv; al != TR_NIL; al = al->list_node.next) 126766Speter argc++; 127766Speter 128766Speter /* 129766Speter * Switch on the operator 130766Speter * associated with the built-in 131766Speter * procedure in the namelist 132766Speter */ 133766Speter op = p->value[0] &~ NSTAND; 134766Speter if (opt('s') && (p->value[0] & NSTAND)) { 135766Speter standard(); 136766Speter error("%s is a nonstandard procedure", p->symbol); 137766Speter } 138766Speter switch (op) { 139766Speter 140766Speter case O_ABORT: 141766Speter if (argc != 0) 142766Speter error("null takes no arguments"); 143766Speter return; 144766Speter 145766Speter case O_FLUSH: 146766Speter if (argc == 0) { 14718467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" ); 14818467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 149766Speter putdot( filename , line ); 150766Speter return; 151766Speter } 152766Speter if (argc != 1) { 153766Speter error("flush takes at most one argument"); 154766Speter return; 155766Speter } 15618467Sralph putleaf( PCC_ICON , 0 , 0 15718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 158766Speter , "_FLUSH" ); 15915934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 16015934Smckusick if (ap == NLNIL) 161766Speter return; 162766Speter if (ap->class != FILET) { 163766Speter error("flush's argument must be a file, not %s", nameof(ap)); 164766Speter return; 165766Speter } 16618467Sralph putop( PCC_CALL , PCCT_INT ); 167766Speter putdot( filename , line ); 168766Speter return; 169766Speter 170766Speter case O_MESSAGE: 171766Speter case O_WRITEF: 172766Speter case O_WRITLN: 173766Speter /* 174766Speter * Set up default file "output"'s type 175766Speter */ 176766Speter file = NIL; 177766Speter filetype = nl+T1CHAR; 178766Speter /* 179766Speter * Determine the file implied 180766Speter * for the write and generate 181766Speter * code to make it the active file. 182766Speter */ 183766Speter if (op == O_MESSAGE) { 184766Speter /* 185766Speter * For message, all that matters 186766Speter * is that the filetype is 187766Speter * a character file. 188766Speter * Thus "output" will suit us fine. 189766Speter */ 19018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" ); 19118467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 192766Speter putdot( filename , line ); 19315934Smckusick putRV( (char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 19418467Sralph PCCTM_PTR|PCCT_STRTY ); 19518467Sralph putLV( "__err" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 19618467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 197766Speter putdot( filename , line ); 19815934Smckusick } else if (argv != TR_NIL && (al = argv->list_node.list)->tag != 19915934Smckusick T_WEXP) { 200766Speter /* 201766Speter * If there is a first argument which has 202766Speter * no write widths, then it is potentially 203766Speter * a file name. 204766Speter */ 205766Speter codeoff(); 20615934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 207766Speter codeon(); 20815934Smckusick if (ap == NLNIL) 20915934Smckusick argv = argv->list_node.next; 210766Speter if (ap != NIL && ap->class == FILET) { 211766Speter /* 212766Speter * Got "write(f, ...", make 213766Speter * f the active file, and save 214766Speter * it and its type for use in 215766Speter * processing the rest of the 216766Speter * arguments to write. 217766Speter */ 21815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 21918467Sralph PCCTM_PTR|PCCT_STRTY ); 22018467Sralph putleaf( PCC_ICON , 0 , 0 22118467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 222766Speter , "_UNIT" ); 22315934Smckusick file = argv->list_node.list; 224766Speter filetype = ap->type; 22515934Smckusick (void) stklval(argv->list_node.list, NOFLAGS); 22618467Sralph putop( PCC_CALL , PCCT_INT ); 22718467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 228766Speter putdot( filename , line ); 229766Speter /* 230766Speter * Skip over the first argument 231766Speter */ 23215934Smckusick argv = argv->list_node.next; 233766Speter argc--; 234766Speter } else { 235766Speter /* 236766Speter * Set up for writing on 237766Speter * standard output. 238766Speter */ 23915934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , 24018467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 2413833Speter putLV( "_output" , 0 , 0 , NGLOBAL , 24218467Sralph PCCTM_PTR|PCCT_STRTY ); 24318467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 244766Speter putdot( filename , line ); 2457954Speter output->nl_flags |= NUSED; 246766Speter } 247766Speter } else { 24815934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 24918467Sralph PCCTM_PTR|PCCT_STRTY ); 25018467Sralph putLV( "_output" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 25118467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 252766Speter putdot( filename , line ); 2537954Speter output->nl_flags |= NUSED; 254766Speter } 255766Speter /* 256766Speter * Loop and process each 257766Speter * of the arguments. 258766Speter */ 25915934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 26015935Smckusick soffset_flag = FALSE; 261766Speter /* 262766Speter * fmtspec indicates the type (CONstant or VARiable) 263766Speter * and number (none, WIDTH, and/or PRECision) 264766Speter * of the fields in the printf format for this 265766Speter * output variable. 266766Speter * fmt is the format output indicator (D, E, F, O, X, S) 267766Speter * fmtstart = 0 for leading blank; = 1 for no blank 268766Speter */ 269766Speter fmtspec = NIL; 270766Speter fmt = 'D'; 271766Speter fmtstart = 1; 27215934Smckusick al = argv->list_node.list; 273766Speter if (al == NIL) 274766Speter continue; 27515934Smckusick if (al->tag == T_WEXP) 27615934Smckusick alv = al->wexpr_node.expr1; 277766Speter else 278766Speter alv = al; 27915934Smckusick if (alv == TR_NIL) 280766Speter continue; 281766Speter codeoff(); 28215934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 283766Speter codeon(); 28415934Smckusick if (ap == NLNIL) 285766Speter continue; 286766Speter typ = classify(ap); 28715934Smckusick if (al->tag == T_WEXP) { 288766Speter /* 289766Speter * Handle width expressions. 290766Speter * The basic game here is that width 291766Speter * expressions get evaluated. If they 292766Speter * are constant, the value is placed 293766Speter * directly in the format string. 294766Speter * Otherwise the value is pushed onto 295766Speter * the stack and an indirection is 296766Speter * put into the format string. 297766Speter */ 29815934Smckusick if (al->wexpr_node.expr3 == 29915934Smckusick (struct tnode *) OCT) 300766Speter fmt = 'O'; 30115934Smckusick else if (al->wexpr_node.expr3 == 30215934Smckusick (struct tnode *) HEX) 303766Speter fmt = 'X'; 30415934Smckusick else if (al->wexpr_node.expr3 != TR_NIL) { 305766Speter /* 306766Speter * Evaluate second format spec 307766Speter */ 30815934Smckusick if ( constval(al->wexpr_node.expr3) 309766Speter && isa( con.ctype , "i" ) ) { 310766Speter fmtspec += CONPREC; 311766Speter prec = con.crval; 312766Speter } else { 313766Speter fmtspec += VARPREC; 314766Speter } 315766Speter fmt = 'f'; 316766Speter switch ( typ ) { 317766Speter case TINT: 318766Speter if ( opt( 's' ) ) { 319766Speter standard(); 320766Speter error("Writing %ss with two write widths is non-standard", clnames[typ]); 321766Speter } 322766Speter /* and fall through */ 323766Speter case TDOUBLE: 324766Speter break; 325766Speter default: 326766Speter error("Cannot write %ss with two write widths", clnames[typ]); 327766Speter continue; 328766Speter } 329766Speter } 330766Speter /* 331766Speter * Evaluate first format spec 332766Speter */ 33315934Smckusick if (al->wexpr_node.expr2 != TR_NIL) { 33415934Smckusick if ( constval(al->wexpr_node.expr2) 335766Speter && isa( con.ctype , "i" ) ) { 336766Speter fmtspec += CONWIDTH; 337766Speter field = con.crval; 338766Speter } else { 339766Speter fmtspec += VARWIDTH; 340766Speter } 341766Speter } 342766Speter if ((fmtspec & CONPREC) && prec < 0 || 343766Speter (fmtspec & CONWIDTH) && field < 0) { 344766Speter error("Negative widths are not allowed"); 345766Speter continue; 346766Speter } 3473180Smckusic if ( opt('s') && 3483180Smckusic ((fmtspec & CONPREC) && prec == 0 || 3493180Smckusic (fmtspec & CONWIDTH) && field == 0)) { 3503180Smckusic standard(); 3513180Smckusic error("Zero widths are non-standard"); 3523180Smckusic } 353766Speter } 354766Speter if (filetype != nl+T1CHAR) { 355766Speter if (fmt == 'O' || fmt == 'X') { 356766Speter error("Oct/hex allowed only on text files"); 357766Speter continue; 358766Speter } 359766Speter if (fmtspec) { 360766Speter error("Write widths allowed only on text files"); 361766Speter continue; 362766Speter } 363766Speter /* 364766Speter * Generalized write, i.e. 365766Speter * to a non-textfile. 366766Speter */ 36718467Sralph putleaf( PCC_ICON , 0 , 0 36818467Sralph , (int) (PCCM_ADDTYPE( 36918467Sralph PCCM_ADDTYPE( 37018467Sralph PCCM_ADDTYPE( p2type( filetype ) 37118467Sralph , PCCTM_PTR ) 37218467Sralph , PCCTM_FTN ) 37318467Sralph , PCCTM_PTR )) 374766Speter , "_FNIL" ); 37515934Smckusick (void) stklval(file, NOFLAGS); 37618467Sralph putop( PCC_CALL 37718467Sralph , PCCM_ADDTYPE( p2type( filetype ) , PCCTM_PTR ) ); 37818467Sralph putop( PCCOM_UNARY PCC_MUL , p2type( filetype ) ); 379766Speter /* 380766Speter * file^ := ... 381766Speter */ 382766Speter switch ( classify( filetype ) ) { 383766Speter case TBOOL: 384766Speter case TCHAR: 385766Speter case TINT: 386766Speter case TSCAL: 3874589Speter precheck( filetype , "_RANG4" , "_RSNG4" ); 388766Speter /* and fall through */ 389766Speter case TDOUBLE: 390766Speter case TPTR: 39115934Smckusick ap = rvalue( argv->list_node.list , filetype , RREQ ); 392766Speter break; 393766Speter default: 39415934Smckusick ap = rvalue( argv->list_node.list , filetype , LREQ ); 395766Speter break; 396766Speter } 397766Speter if (ap == NIL) 398766Speter continue; 39915934Smckusick if (incompat(ap, filetype, argv->list_node.list)) { 400766Speter cerror("Type mismatch in write to non-text file"); 401766Speter continue; 402766Speter } 403766Speter switch ( classify( filetype ) ) { 404766Speter case TBOOL: 405766Speter case TCHAR: 406766Speter case TINT: 407766Speter case TSCAL: 40810373Speter postcheck(filetype, ap); 40910373Speter sconv(p2type(ap), p2type(filetype)); 410766Speter /* and fall through */ 411766Speter case TDOUBLE: 412766Speter case TPTR: 41318467Sralph putop( PCC_ASSIGN , p2type( filetype ) ); 414766Speter putdot( filename , line ); 415766Speter break; 416766Speter default: 41718467Sralph putstrop(PCC_STASG, 41818467Sralph PCCM_ADDTYPE(p2type(filetype), 41918467Sralph PCCTM_PTR), 42015934Smckusick (int) lwidth(filetype), 42111856Speter align(filetype)); 422766Speter putdot( filename , line ); 423766Speter break; 424766Speter } 425766Speter /* 426766Speter * put(file) 427766Speter */ 42818467Sralph putleaf( PCC_ICON , 0 , 0 42918467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 430766Speter , "_PUT" ); 43115934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 43218467Sralph PCCTM_PTR|PCCT_STRTY ); 43318467Sralph putop( PCC_CALL , PCCT_INT ); 434766Speter putdot( filename , line ); 435766Speter continue; 436766Speter } 437766Speter /* 438766Speter * Write to a textfile 439766Speter * 440766Speter * Evaluate the expression 441766Speter * to be written. 442766Speter */ 443766Speter if (fmt == 'O' || fmt == 'X') { 444766Speter if (opt('s')) { 445766Speter standard(); 446766Speter error("Oct and hex are non-standard"); 447766Speter } 448766Speter if (typ == TSTR || typ == TDOUBLE) { 449766Speter error("Can't write %ss with oct/hex", clnames[typ]); 450766Speter continue; 451766Speter } 452766Speter if (typ == TCHAR || typ == TBOOL) 453766Speter typ = TINT; 454766Speter } 455766Speter /* 456766Speter * If there is no format specified by the programmer, 457766Speter * implement the default. 458766Speter */ 459766Speter switch (typ) { 4606540Smckusick case TPTR: 4616540Smckusick warning(); 4626540Smckusick if (opt('s')) { 4636540Smckusick standard(); 4646540Smckusick } 4656540Smckusick error("Writing %ss to text files is non-standard", 4666540Smckusick clnames[typ]); 4676540Smckusick /* and fall through */ 468766Speter case TINT: 469766Speter if (fmt == 'f') { 470766Speter typ = TDOUBLE; 471766Speter goto tdouble; 472766Speter } 473766Speter if (fmtspec == NIL) { 474766Speter if (fmt == 'D') 475766Speter field = 10; 476766Speter else if (fmt == 'X') 477766Speter field = 8; 478766Speter else if (fmt == 'O') 479766Speter field = 11; 480766Speter else 481766Speter panic("fmt1"); 482766Speter fmtspec = CONWIDTH; 483766Speter } 484766Speter break; 485766Speter case TCHAR: 486766Speter tchar: 487766Speter fmt = 'c'; 488766Speter break; 489766Speter case TSCAL: 4901629Speter warning(); 491766Speter if (opt('s')) { 492766Speter standard(); 493766Speter } 4946540Smckusick error("Writing %ss to text files is non-standard", 4956540Smckusick clnames[typ]); 496766Speter case TBOOL: 497766Speter fmt = 's'; 498766Speter break; 499766Speter case TDOUBLE: 500766Speter tdouble: 501766Speter switch (fmtspec) { 502766Speter case NIL: 50311883Smckusick field = 14 + (5 + EXPOSIZE); 50411883Smckusick prec = field - (5 + EXPOSIZE); 5053225Smckusic fmt = 'e'; 506766Speter fmtspec = CONWIDTH + CONPREC; 507766Speter break; 508766Speter case CONWIDTH: 5099229Smckusick field -= REALSPC; 5109229Smckusick if (field < 1) 511766Speter field = 1; 51211883Smckusick prec = field - (5 + EXPOSIZE); 513766Speter if (prec < 1) 514766Speter prec = 1; 515766Speter fmtspec += CONPREC; 5163225Smckusic fmt = 'e'; 517766Speter break; 518766Speter case VARWIDTH: 519766Speter fmtspec += VARPREC; 5203225Smckusic fmt = 'e'; 521766Speter break; 522766Speter case CONWIDTH + CONPREC: 523766Speter case CONWIDTH + VARPREC: 5249229Smckusick field -= REALSPC; 5259229Smckusick if (field < 1) 526766Speter field = 1; 527766Speter } 528766Speter format[0] = ' '; 5299229Smckusick fmtstart = 1 - REALSPC; 530766Speter break; 531766Speter case TSTR: 53215934Smckusick (void) constval( alv ); 533766Speter switch ( classify( con.ctype ) ) { 534766Speter case TCHAR: 535766Speter typ = TCHAR; 536766Speter goto tchar; 537766Speter case TSTR: 538766Speter strptr = con.cpval; 539766Speter for (strnglen = 0; *strptr++; strnglen++) /* void */; 540766Speter strptr = con.cpval; 541766Speter break; 542766Speter default: 543766Speter strnglen = width(ap); 544766Speter break; 545766Speter } 546766Speter fmt = 's'; 547766Speter strfmt = fmtspec; 548766Speter if (fmtspec == NIL) { 549766Speter fmtspec = SKIP; 550766Speter break; 551766Speter } 552766Speter if (fmtspec & CONWIDTH) { 553766Speter if (field <= strnglen) 554766Speter fmtspec = SKIP; 555766Speter else 556766Speter field -= strnglen; 557766Speter } 558766Speter break; 559766Speter default: 560766Speter error("Can't write %ss to a text file", clnames[typ]); 561766Speter continue; 562766Speter } 563766Speter /* 564766Speter * Generate the format string 565766Speter */ 566766Speter switch (fmtspec) { 567766Speter default: 568766Speter panic("fmt2"); 569766Speter case NIL: 570766Speter if (fmt == 'c') { 571766Speter if ( opt( 't' ) ) { 57218467Sralph putleaf( PCC_ICON , 0 , 0 57318467Sralph , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR ) 574766Speter , "_WRITEC" ); 57515934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 57618467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 57715934Smckusick (void) stkrval( alv , NLNIL , (long) RREQ ); 57818467Sralph putop( PCC_CM , PCCT_INT ); 579766Speter } else { 58018467Sralph putleaf( PCC_ICON , 0 , 0 58118467Sralph , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR ) 582766Speter , "_fputc" ); 58315934Smckusick (void) stkrval( alv , NLNIL , 58415934Smckusick (long) RREQ ); 585766Speter } 58618467Sralph putleaf( PCC_ICON , 0 , 0 58718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 588766Speter , "_ACTFILE" ); 58915934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , 59018467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 59118467Sralph putop( PCC_CALL , PCCT_INT ); 59218467Sralph putop( PCC_CM , PCCT_INT ); 59318467Sralph putop( PCC_CALL , PCCT_INT ); 594766Speter putdot( filename , line ); 595766Speter } else { 596766Speter sprintf(&format[1], "%%%c", fmt); 597766Speter goto fmtgen; 598766Speter } 599766Speter case SKIP: 600766Speter break; 601766Speter case CONWIDTH: 602766Speter sprintf(&format[1], "%%%1D%c", field, fmt); 603766Speter goto fmtgen; 604766Speter case VARWIDTH: 605766Speter sprintf(&format[1], "%%*%c", fmt); 606766Speter goto fmtgen; 607766Speter case CONWIDTH + CONPREC: 608766Speter sprintf(&format[1], "%%%1D.%1D%c", field, prec, fmt); 609766Speter goto fmtgen; 610766Speter case CONWIDTH + VARPREC: 611766Speter sprintf(&format[1], "%%%1D.*%c", field, fmt); 612766Speter goto fmtgen; 613766Speter case VARWIDTH + CONPREC: 614766Speter sprintf(&format[1], "%%*.%1D%c", prec, fmt); 615766Speter goto fmtgen; 616766Speter case VARWIDTH + VARPREC: 617766Speter sprintf(&format[1], "%%*.*%c", fmt); 618766Speter fmtgen: 619766Speter if ( opt( 't' ) ) { 62018467Sralph putleaf( PCC_ICON , 0 , 0 62118467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 622766Speter , "_WRITEF" ); 62315934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 62418467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 62518467Sralph putleaf( PCC_ICON , 0 , 0 62618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 627766Speter , "_ACTFILE" ); 62815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 62918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 63018467Sralph putop( PCC_CALL , PCCT_INT ); 63118467Sralph putop( PCC_CM , PCCT_INT ); 632766Speter } else { 63318467Sralph putleaf( PCC_ICON , 0 , 0 63418467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 635766Speter , "_fprintf" ); 63618467Sralph putleaf( PCC_ICON , 0 , 0 63718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 638766Speter , "_ACTFILE" ); 63915934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 64018467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 64118467Sralph putop( PCC_CALL , PCCT_INT ); 642766Speter } 643766Speter putCONG( &format[ fmtstart ] 644766Speter , strlen( &format[ fmtstart ] ) 645766Speter , LREQ ); 64618467Sralph putop( PCC_CM , PCCT_INT ); 647766Speter if ( fmtspec & VARWIDTH ) { 648766Speter /* 649766Speter * either 650766Speter * ,(temp=width,MAX(temp,...)), 651766Speter * or 652766Speter * , MAX( width , ... ) , 653766Speter */ 65415934Smckusick if ( ( typ == TDOUBLE && 65515934Smckusick al->wexpr_node.expr3 == TR_NIL ) 656766Speter || typ == TSTR ) { 65715935Smckusick soffset_flag = TRUE; 6583225Smckusic soffset = sizes[cbn].curtmps; 65915934Smckusick tempnlp = tmpalloc((long) (sizeof(long)), 6603225Smckusic nl+T4INT, REGOK); 66115934Smckusick putRV((char *) 0 , cbn , 6623833Speter tempnlp -> value[ NL_OFFS ] , 66318467Sralph tempnlp -> extra_flags , PCCT_INT ); 66415934Smckusick ap = stkrval( al->wexpr_node.expr2 , 66515934Smckusick NLNIL , (long) RREQ ); 66618467Sralph putop( PCC_ASSIGN , PCCT_INT ); 66718467Sralph putleaf( PCC_ICON , 0 , 0 66818467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 669766Speter , "_MAX" ); 67015934Smckusick putRV((char *) 0 , cbn , 6713833Speter tempnlp -> value[ NL_OFFS ] , 67218467Sralph tempnlp -> extra_flags , PCCT_INT ); 673766Speter } else { 674766Speter if (opt('t') 675766Speter || typ == TSTR || typ == TDOUBLE) { 67618467Sralph putleaf( PCC_ICON , 0 , 0 67718467Sralph ,PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT, PCCTM_PTR ) 678766Speter ,"_MAX" ); 679766Speter } 68015934Smckusick ap = stkrval( al->wexpr_node.expr2, 68115934Smckusick NLNIL , (long) RREQ ); 682766Speter } 68315934Smckusick if (ap == NLNIL) 684766Speter continue; 685766Speter if (isnta(ap,"i")) { 686766Speter error("First write width must be integer, not %s", nameof(ap)); 687766Speter continue; 688766Speter } 689766Speter switch ( typ ) { 690766Speter case TDOUBLE: 69118467Sralph putleaf( PCC_ICON , REALSPC , 0 , PCCT_INT , (char *) 0 ); 69218467Sralph putop( PCC_CM , PCCT_INT ); 69318467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 69418467Sralph putop( PCC_CM , PCCT_INT ); 69518467Sralph putop( PCC_CALL , PCCT_INT ); 69615934Smckusick if ( al->wexpr_node.expr3 == TR_NIL ) { 697766Speter /* 698766Speter * finish up the comma op 699766Speter */ 70018467Sralph putop( PCC_COMOP , PCCT_INT ); 701766Speter fmtspec &= ~VARPREC; 70218467Sralph putop( PCC_CM , PCCT_INT ); 70318467Sralph putleaf( PCC_ICON , 0 , 0 70418467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 705766Speter , "_MAX" ); 70615934Smckusick putRV((char *) 0 , cbn , 7073833Speter tempnlp -> value[ NL_OFFS ] , 7083833Speter tempnlp -> extra_flags , 70918467Sralph PCCT_INT ); 71018467Sralph putleaf( PCC_ICON , 71111883Smckusick 5 + EXPOSIZE + REALSPC , 71218467Sralph 0 , PCCT_INT , (char *) 0 ); 71318467Sralph putop( PCC_CM , PCCT_INT ); 71418467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 71518467Sralph putop( PCC_CM , PCCT_INT ); 71618467Sralph putop( PCC_CALL , PCCT_INT ); 717766Speter } 71818467Sralph putop( PCC_CM , PCCT_INT ); 719766Speter break; 720766Speter case TSTR: 72118467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 72218467Sralph putop( PCC_CM , PCCT_INT ); 72318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 72418467Sralph putop( PCC_CM , PCCT_INT ); 72518467Sralph putop( PCC_CALL , PCCT_INT ); 72618467Sralph putop( PCC_COMOP , PCCT_INT ); 72718467Sralph putop( PCC_CM , PCCT_INT ); 728766Speter break; 729766Speter default: 730766Speter if (opt('t')) { 73118467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 73218467Sralph putop( PCC_CM , PCCT_INT ); 73318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 73418467Sralph putop( PCC_CM , PCCT_INT ); 73518467Sralph putop( PCC_CALL , PCCT_INT ); 736766Speter } 73718467Sralph putop( PCC_CM , PCCT_INT ); 738766Speter break; 739766Speter } 740766Speter } 741766Speter /* 742766Speter * If there is a variable precision, 743766Speter * evaluate it 744766Speter */ 745766Speter if (fmtspec & VARPREC) { 746766Speter if (opt('t')) { 74718467Sralph putleaf( PCC_ICON , 0 , 0 74818467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 749766Speter , "_MAX" ); 750766Speter } 75115934Smckusick ap = stkrval( al->wexpr_node.expr3 , 75215934Smckusick NLNIL , (long) RREQ ); 753766Speter if (ap == NIL) 754766Speter continue; 755766Speter if (isnta(ap,"i")) { 756766Speter error("Second write width must be integer, not %s", nameof(ap)); 757766Speter continue; 758766Speter } 759766Speter if (opt('t')) { 76018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 76118467Sralph putop( PCC_CM , PCCT_INT ); 76218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 76318467Sralph putop( PCC_CM , PCCT_INT ); 76418467Sralph putop( PCC_CALL , PCCT_INT ); 765766Speter } 76618467Sralph putop( PCC_CM , PCCT_INT ); 767766Speter } 768766Speter /* 769766Speter * evaluate the thing we want printed. 770766Speter */ 771766Speter switch ( typ ) { 7726540Smckusick case TPTR: 773766Speter case TCHAR: 774766Speter case TINT: 77515934Smckusick (void) stkrval( alv , NLNIL , (long) RREQ ); 77618467Sralph putop( PCC_CM , PCCT_INT ); 777766Speter break; 778766Speter case TDOUBLE: 77915934Smckusick ap = stkrval( alv , NLNIL , (long) RREQ ); 78010373Speter if (isnta(ap, "d")) { 78118467Sralph sconv(p2type(ap), PCCT_DOUBLE); 782766Speter } 78318467Sralph putop( PCC_CM , PCCT_INT ); 784766Speter break; 785766Speter case TSCAL: 786766Speter case TBOOL: 78718467Sralph putleaf( PCC_ICON , 0 , 0 78818467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 789766Speter , "_NAM" ); 79015934Smckusick ap = stkrval( alv , NLNIL , (long) RREQ ); 791766Speter sprintf( format , PREFIXFORMAT , LABELPREFIX 792766Speter , listnames( ap ) ); 79318467Sralph putleaf( PCC_ICON , 0 , 0 , 79418467Sralph (int) (PCCTM_PTR | PCCT_CHAR), format ); 79518467Sralph putop( PCC_CM , PCCT_INT ); 79618467Sralph putop( PCC_CALL , PCCT_INT ); 79718467Sralph putop( PCC_CM , PCCT_INT ); 798766Speter break; 799766Speter case TSTR: 800766Speter putCONG( "" , 0 , LREQ ); 80118467Sralph putop( PCC_CM , PCCT_INT ); 802766Speter break; 8036540Smckusick default: 8046540Smckusick panic("fmt3"); 8056540Smckusick break; 806766Speter } 80718467Sralph putop( PCC_CALL , PCCT_INT ); 808766Speter putdot( filename , line ); 809766Speter } 810766Speter /* 811766Speter * Write the string after its blank padding 812766Speter */ 813766Speter if (typ == TSTR ) { 814766Speter if ( opt( 't' ) ) { 81518467Sralph putleaf( PCC_ICON , 0 , 0 81618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 817766Speter , "_WRITES" ); 81815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 81918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 82015934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 82118467Sralph putop( PCC_CM , PCCT_INT ); 822766Speter } else { 82318467Sralph putleaf( PCC_ICON , 0 , 0 82418467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 825766Speter , "_fwrite" ); 82615934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 827766Speter } 828766Speter if (strfmt & VARWIDTH) { 829766Speter /* 830766Speter * min, inline expanded as 831766Speter * temp < len ? temp : len 832766Speter */ 83315934Smckusick putRV((char *) 0 , cbn , 8343833Speter tempnlp -> value[ NL_OFFS ] , 83518467Sralph tempnlp -> extra_flags , PCCT_INT ); 83618467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 83718467Sralph putop( PCC_LT , PCCT_INT ); 83815934Smckusick putRV((char *) 0 , cbn , 8393833Speter tempnlp -> value[ NL_OFFS ] , 84018467Sralph tempnlp -> extra_flags , PCCT_INT ); 84118467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 84218467Sralph putop( PCC_COLON , PCCT_INT ); 84318467Sralph putop( PCC_QUEST , PCCT_INT ); 844766Speter } else { 845766Speter if ( ( fmtspec & SKIP ) 846766Speter && ( strfmt & CONWIDTH ) ) { 847766Speter strnglen = field; 848766Speter } 84918467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 850766Speter } 85118467Sralph putop( PCC_CM , PCCT_INT ); 85218467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 85318467Sralph putop( PCC_CM , PCCT_INT ); 85418467Sralph putleaf( PCC_ICON , 0 , 0 85518467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 856766Speter , "_ACTFILE" ); 85715934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 85818467Sralph PCCTM_PTR|PCCT_STRTY ); 85918467Sralph putop( PCC_CALL , PCCT_INT ); 86018467Sralph putop( PCC_CM , PCCT_INT ); 86118467Sralph putop( PCC_CALL , PCCT_INT ); 862766Speter putdot( filename , line ); 863766Speter } 86415935Smckusick if (soffset_flag) { 86515935Smckusick tmpfree(&soffset); 86615935Smckusick soffset_flag = FALSE; 86715935Smckusick } 868766Speter } 869766Speter /* 870766Speter * Done with arguments. 871766Speter * Handle writeln and 872766Speter * insufficent number of args. 873766Speter */ 874766Speter switch (p->value[0] &~ NSTAND) { 875766Speter case O_WRITEF: 876766Speter if (argc == 0) 877766Speter error("Write requires an argument"); 878766Speter break; 879766Speter case O_MESSAGE: 880766Speter if (argc == 0) 881766Speter error("Message requires an argument"); 882766Speter case O_WRITLN: 883766Speter if (filetype != nl+T1CHAR) 884766Speter error("Can't 'writeln' a non text file"); 885766Speter if ( opt( 't' ) ) { 88618467Sralph putleaf( PCC_ICON , 0 , 0 88718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 888766Speter , "_WRITLN" ); 88915934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 89018467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 891766Speter } else { 89218467Sralph putleaf( PCC_ICON , 0 , 0 89318467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 894766Speter , "_fputc" ); 89518467Sralph putleaf( PCC_ICON , '\n' , 0 , (int) PCCT_CHAR , (char *) 0 ); 89618467Sralph putleaf( PCC_ICON , 0 , 0 89718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 898766Speter , "_ACTFILE" ); 89915934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 90018467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 90118467Sralph putop( PCC_CALL , PCCT_INT ); 90218467Sralph putop( PCC_CM , PCCT_INT ); 903766Speter } 90418467Sralph putop( PCC_CALL , PCCT_INT ); 905766Speter putdot( filename , line ); 906766Speter break; 907766Speter } 908766Speter return; 909766Speter 910766Speter case O_READ4: 911766Speter case O_READLN: 912766Speter /* 913766Speter * Set up default 914766Speter * file "input". 915766Speter */ 916766Speter file = NIL; 917766Speter filetype = nl+T1CHAR; 918766Speter /* 919766Speter * Determine the file implied 920766Speter * for the read and generate 921766Speter * code to make it the active file. 922766Speter */ 92315934Smckusick if (argv != TR_NIL) { 924766Speter codeoff(); 92515934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 926766Speter codeon(); 92715934Smckusick if (ap == NLNIL) 92815934Smckusick argv = argv->list_node.next; 92915934Smckusick if (ap != NLNIL && ap->class == FILET) { 930766Speter /* 931766Speter * Got "read(f, ...", make 932766Speter * f the active file, and save 933766Speter * it and its type for use in 934766Speter * processing the rest of the 935766Speter * arguments to read. 936766Speter */ 93715934Smckusick file = argv->list_node.list; 938766Speter filetype = ap->type; 93915934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 94018467Sralph PCCTM_PTR|PCCT_STRTY ); 94118467Sralph putleaf( PCC_ICON , 0 , 0 94218467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 943766Speter , "_UNIT" ); 94415934Smckusick (void) stklval(argv->list_node.list, NOFLAGS); 94518467Sralph putop( PCC_CALL , PCCT_INT ); 94618467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 947766Speter putdot( filename , line ); 94815934Smckusick argv = argv->list_node.next; 949766Speter argc--; 950766Speter } else { 951766Speter /* 952766Speter * Default is read from 953766Speter * standard input. 954766Speter */ 95515934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 95618467Sralph PCCTM_PTR|PCCT_STRTY ); 9573833Speter putLV( "_input" , 0 , 0 , NGLOBAL , 95818467Sralph PCCTM_PTR|PCCT_STRTY ); 95918467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 960766Speter putdot( filename , line ); 961766Speter input->nl_flags |= NUSED; 962766Speter } 963766Speter } else { 96415934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 96518467Sralph PCCTM_PTR|PCCT_STRTY ); 96618467Sralph putLV( "_input" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 96718467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 968766Speter putdot( filename , line ); 969766Speter input->nl_flags |= NUSED; 970766Speter } 971766Speter /* 972766Speter * Loop and process each 973766Speter * of the arguments. 974766Speter */ 97515934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 976766Speter /* 977766Speter * Get the address of the target 978766Speter * on the stack. 979766Speter */ 98015934Smckusick al = argv->list_node.list; 98115934Smckusick if (al == TR_NIL) 982766Speter continue; 98315934Smckusick if (al->tag != T_VAR) { 984766Speter error("Arguments to %s must be variables, not expressions", p->symbol); 985766Speter continue; 986766Speter } 987766Speter codeoff(); 988766Speter ap = stklval(al, MOD|ASGN|NOUSE); 989766Speter codeon(); 99015934Smckusick if (ap == NLNIL) 991766Speter continue; 992766Speter if (filetype != nl+T1CHAR) { 993766Speter /* 994766Speter * Generalized read, i.e. 995766Speter * from a non-textfile. 996766Speter */ 99715934Smckusick if (incompat(filetype, ap, argv->list_node.list )) { 998766Speter error("Type mismatch in read from non-text file"); 999766Speter continue; 1000766Speter } 1001766Speter /* 1002766Speter * var := file ^; 1003766Speter */ 1004766Speter ap = lvalue( al , MOD | ASGN | NOUSE , RREQ ); 1005766Speter if ( isa( ap , "bsci" ) ) { 1006766Speter precheck( ap , "_RANG4" , "_RSNG4" ); 1007766Speter } 100818467Sralph putleaf( PCC_ICON , 0 , 0 100918467Sralph , (int) (PCCM_ADDTYPE( 101018467Sralph PCCM_ADDTYPE( 101118467Sralph PCCM_ADDTYPE( 101218467Sralph p2type( filetype ) , PCCTM_PTR ) 101318467Sralph , PCCTM_FTN ) 101418467Sralph , PCCTM_PTR )) 1015766Speter , "_FNIL" ); 1016766Speter if (file != NIL) 101715934Smckusick (void) stklval(file, NOFLAGS); 1018766Speter else /* Magic */ 10193833Speter putRV( "_input" , 0 , 0 , NGLOBAL , 102018467Sralph PCCTM_PTR | PCCT_STRTY ); 102118467Sralph putop(PCC_CALL, PCCM_ADDTYPE(p2type(filetype), PCCTM_PTR)); 1022766Speter switch ( classify( filetype ) ) { 1023766Speter case TBOOL: 1024766Speter case TCHAR: 1025766Speter case TINT: 1026766Speter case TSCAL: 1027766Speter case TDOUBLE: 1028766Speter case TPTR: 102918467Sralph putop( PCCOM_UNARY PCC_MUL 1030766Speter , p2type( filetype ) ); 1031766Speter } 1032766Speter switch ( classify( filetype ) ) { 1033766Speter case TBOOL: 1034766Speter case TCHAR: 1035766Speter case TINT: 1036766Speter case TSCAL: 103710373Speter postcheck(ap, filetype); 103810373Speter sconv(p2type(filetype), p2type(ap)); 1039766Speter /* and fall through */ 1040766Speter case TDOUBLE: 1041766Speter case TPTR: 104218467Sralph putop( PCC_ASSIGN , p2type( ap ) ); 1043766Speter putdot( filename , line ); 1044766Speter break; 1045766Speter default: 104618467Sralph putstrop(PCC_STASG, 104718467Sralph PCCM_ADDTYPE(p2type(ap), PCCTM_PTR), 104815934Smckusick (int) lwidth(ap), 104911856Speter align(ap)); 1050766Speter putdot( filename , line ); 1051766Speter break; 1052766Speter } 1053766Speter /* 1054766Speter * get(file); 1055766Speter */ 105618467Sralph putleaf( PCC_ICON , 0 , 0 105718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1058766Speter , "_GET" ); 105915934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 106018467Sralph PCCTM_PTR|PCCT_STRTY ); 106118467Sralph putop( PCC_CALL , PCCT_INT ); 1062766Speter putdot( filename , line ); 1063766Speter continue; 1064766Speter } 1065766Speter /* 1066766Speter * if you get to here, you are reading from 1067766Speter * a text file. only possiblities are: 1068766Speter * character, integer, real, or scalar. 1069766Speter * read( f , foo , ... ) is done as 1070766Speter * foo := read( f ) with rangechecking 1071766Speter * if appropriate. 1072766Speter */ 1073766Speter typ = classify(ap); 1074766Speter op = rdops(typ); 1075766Speter if (op == NIL) { 1076766Speter error("Can't read %ss from a text file", clnames[typ]); 1077766Speter continue; 1078766Speter } 1079766Speter /* 1080766Speter * left hand side of foo := read( f ) 1081766Speter */ 1082766Speter ap = lvalue( al , MOD|ASGN|NOUSE , RREQ ); 1083766Speter if ( isa( ap , "bsci" ) ) { 1084766Speter precheck( ap , "_RANG4" , "_RSNG4" ); 1085766Speter } 1086766Speter switch ( op ) { 1087766Speter case O_READC: 1088766Speter readname = "_READC"; 108918467Sralph readtype = PCCT_INT; 1090766Speter break; 1091766Speter case O_READ4: 1092766Speter readname = "_READ4"; 109318467Sralph readtype = PCCT_INT; 1094766Speter break; 1095766Speter case O_READ8: 1096766Speter readname = "_READ8"; 109718467Sralph readtype = PCCT_DOUBLE; 1098766Speter break; 1099766Speter case O_READE: 1100766Speter readname = "_READE"; 110118467Sralph readtype = PCCT_INT; 1102766Speter break; 1103766Speter } 110418467Sralph putleaf( PCC_ICON , 0 , 0 110518467Sralph , (int) PCCM_ADDTYPE( PCCTM_FTN | readtype , PCCTM_PTR ) 1106766Speter , readname ); 110715934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 110818467Sralph PCCTM_PTR|PCCT_STRTY ); 1109766Speter if ( op == O_READE ) { 1110766Speter sprintf( format , PREFIXFORMAT , LABELPREFIX 1111766Speter , listnames( ap ) ); 111218467Sralph putleaf( PCC_ICON , 0, 0, (int) (PCCTM_PTR | PCCT_CHAR), 111315934Smckusick format ); 111418467Sralph putop( PCC_CM , PCCT_INT ); 11151629Speter warning(); 1116766Speter if (opt('s')) { 1117766Speter standard(); 1118766Speter } 11191629Speter error("Reading scalars from text files is non-standard"); 1120766Speter } 112118467Sralph putop( PCC_CALL , (int) readtype ); 1122766Speter if ( isa( ap , "bcsi" ) ) { 112318467Sralph postcheck(ap, readtype==PCCT_INT?nl+T4INT:nl+TDOUBLE); 1124766Speter } 112515934Smckusick sconv((int) readtype, p2type(ap)); 112618467Sralph putop( PCC_ASSIGN , p2type( ap ) ); 1127766Speter putdot( filename , line ); 1128766Speter } 1129766Speter /* 1130766Speter * Done with arguments. 1131766Speter * Handle readln and 1132766Speter * insufficient number of args. 1133766Speter */ 1134766Speter if (p->value[0] == O_READLN) { 1135766Speter if (filetype != nl+T1CHAR) 1136766Speter error("Can't 'readln' a non text file"); 113718467Sralph putleaf( PCC_ICON , 0 , 0 113818467Sralph , (int) PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1139766Speter , "_READLN" ); 114015934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 114118467Sralph PCCTM_PTR|PCCT_STRTY ); 114218467Sralph putop( PCC_CALL , PCCT_INT ); 1143766Speter putdot( filename , line ); 1144766Speter } else if (argc == 0) 1145766Speter error("read requires an argument"); 1146766Speter return; 1147766Speter 1148766Speter case O_GET: 1149766Speter case O_PUT: 1150766Speter if (argc != 1) { 1151766Speter error("%s expects one argument", p->symbol); 1152766Speter return; 1153766Speter } 115418467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 115518467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1156766Speter , "_UNIT" ); 115715934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 115815934Smckusick if (ap == NLNIL) 1159766Speter return; 1160766Speter if (ap->class != FILET) { 1161766Speter error("Argument to %s must be a file, not %s", p->symbol, nameof(ap)); 1162766Speter return; 1163766Speter } 116418467Sralph putop( PCC_CALL , PCCT_INT ); 116518467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 1166766Speter putdot( filename , line ); 116718467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1168766Speter , op == O_GET ? "_GET" : "_PUT" ); 116918467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 117018467Sralph putop( PCC_CALL , PCCT_INT ); 1171766Speter putdot( filename , line ); 1172766Speter return; 1173766Speter 1174766Speter case O_RESET: 1175766Speter case O_REWRITE: 1176766Speter if (argc == 0 || argc > 2) { 1177766Speter error("%s expects one or two arguments", p->symbol); 1178766Speter return; 1179766Speter } 1180766Speter if (opt('s') && argc == 2) { 1181766Speter standard(); 1182766Speter error("Two argument forms of reset and rewrite are non-standard"); 1183766Speter } 118418467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT 1185766Speter , op == O_RESET ? "_RESET" : "_REWRITE" ); 118615934Smckusick ap = stklval(argv->list_node.list, MOD|NOUSE); 118715934Smckusick if (ap == NLNIL) 1188766Speter return; 1189766Speter if (ap->class != FILET) { 1190766Speter error("First argument to %s must be a file, not %s", p->symbol, nameof(ap)); 1191766Speter return; 1192766Speter } 1193766Speter if (argc == 2) { 1194766Speter /* 1195766Speter * Optional second argument 1196766Speter * is a string name of a 1197766Speter * UNIX (R) file to be associated. 1198766Speter */ 119915934Smckusick al = argv->list_node.next; 120015934Smckusick al = (struct tnode *) stkrval(al->list_node.list, 120115934Smckusick NLNIL , (long) RREQ ); 120215934Smckusick if (al == TR_NIL) 1203766Speter return; 120415934Smckusick if (classify((struct nl *) al) != TSTR) { 120515934Smckusick error("Second argument to %s must be a string, not %s", p->symbol, nameof((struct nl *) al)); 1206766Speter return; 1207766Speter } 120815934Smckusick strnglen = width((struct nl *) al); 1209766Speter } else { 121018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 1211766Speter strnglen = 0; 1212766Speter } 121318467Sralph putop( PCC_CM , PCCT_INT ); 121418467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 121518467Sralph putop( PCC_CM , PCCT_INT ); 121618467Sralph putleaf( PCC_ICON , text(ap) ? 0: width(ap->type) , 0 , PCCT_INT , (char *) 0 ); 121718467Sralph putop( PCC_CM , PCCT_INT ); 121818467Sralph putop( PCC_CALL , PCCT_INT ); 1219766Speter putdot( filename , line ); 1220766Speter return; 1221766Speter 1222766Speter case O_NEW: 1223766Speter case O_DISPOSE: 1224766Speter if (argc == 0) { 1225766Speter error("%s expects at least one argument", p->symbol); 1226766Speter return; 1227766Speter } 122815934Smckusick alv = argv->list_node.list; 12297967Smckusick codeoff(); 12309139Smckusick ap = stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD ); 12317967Smckusick codeon(); 123215934Smckusick if (ap == NLNIL) 1233766Speter return; 1234766Speter if (ap->class != PTR) { 1235766Speter error("(First) argument to %s must be a pointer, not %s", p->symbol, nameof(ap)); 1236766Speter return; 1237766Speter } 1238766Speter ap = ap->type; 123915934Smckusick if (ap == NLNIL) 1240766Speter return; 12419139Smckusick if (op == O_NEW) 12429139Smckusick cmd = "_NEW"; 12439139Smckusick else /* op == O_DISPOSE */ 12447967Smckusick if ((ap->nl_flags & NFILES) != 0) 12457967Smckusick cmd = "_DFDISPOSE"; 12467967Smckusick else 12477967Smckusick cmd = "_DISPOSE"; 124818467Sralph putleaf( PCC_ICON, 0, 0, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ), cmd); 124915934Smckusick (void) stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD ); 125015934Smckusick argv = argv->list_node.next; 125115934Smckusick if (argv != TR_NIL) { 1252766Speter if (ap->class != RECORD) { 1253766Speter error("Record required when specifying variant tags"); 1254766Speter return; 1255766Speter } 125615934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 1257766Speter if (ap->ptr[NL_VARNT] == NIL) { 1258766Speter error("Too many tag fields"); 1259766Speter return; 1260766Speter } 126115934Smckusick if (!isconst(argv->list_node.list)) { 1262766Speter error("Second and successive arguments to %s must be constants", p->symbol); 1263766Speter return; 1264766Speter } 126515934Smckusick gconst(argv->list_node.list); 1266766Speter if (con.ctype == NIL) 1267766Speter return; 126815934Smckusick if (incompat(con.ctype, (ap->ptr[NL_TAG])->type , TR_NIL )) { 1269766Speter cerror("Specified tag constant type clashed with variant case selector type"); 1270766Speter return; 1271766Speter } 1272766Speter for (ap = ap->ptr[NL_VARNT]; ap != NIL; ap = ap->chain) 1273766Speter if (ap->range[0] == con.crval) 1274766Speter break; 1275766Speter if (ap == NIL) { 1276766Speter error("No variant case label value equals specified constant value"); 1277766Speter return; 1278766Speter } 1279766Speter ap = ap->ptr[NL_VTOREC]; 1280766Speter } 1281766Speter } 128218467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 128318467Sralph putop( PCC_CM , PCCT_INT ); 128418467Sralph putop( PCC_CALL , PCCT_INT ); 1285766Speter putdot( filename , line ); 12869139Smckusick if (opt('t') && op == O_NEW) { 128718467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 12889139Smckusick , "_blkclr" ); 128915934Smckusick (void) stkrval(alv, NLNIL , (long) RREQ ); 129018467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 129118467Sralph putop( PCC_CM , PCCT_INT ); 129218467Sralph putop( PCC_CALL , PCCT_INT ); 12939139Smckusick putdot( filename , line ); 12949139Smckusick } 1295766Speter return; 1296766Speter 1297766Speter case O_DATE: 1298766Speter case O_TIME: 1299766Speter if (argc != 1) { 1300766Speter error("%s expects one argument", p->symbol); 1301766Speter return; 1302766Speter } 130318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1304766Speter , op == O_DATE ? "_DATE" : "_TIME" ); 130515934Smckusick ap = stklval(argv->list_node.list, MOD|NOUSE); 1306766Speter if (ap == NIL) 1307766Speter return; 1308766Speter if (classify(ap) != TSTR || width(ap) != 10) { 1309766Speter error("Argument to %s must be a alfa, not %s", p->symbol, nameof(ap)); 1310766Speter return; 1311766Speter } 131218467Sralph putop( PCC_CALL , PCCT_INT ); 1313766Speter putdot( filename , line ); 1314766Speter return; 1315766Speter 1316766Speter case O_HALT: 1317766Speter if (argc != 0) { 1318766Speter error("halt takes no arguments"); 1319766Speter return; 1320766Speter } 132118467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1322766Speter , "_HALT" ); 1323766Speter 132418467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 1325766Speter putdot( filename , line ); 132615934Smckusick noreach = TRUE; 1327766Speter return; 1328766Speter 1329766Speter case O_ARGV: 1330766Speter if (argc != 2) { 1331766Speter error("argv takes two arguments"); 1332766Speter return; 1333766Speter } 133418467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1335766Speter , "_ARGV" ); 133615934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 133715934Smckusick if (ap == NLNIL) 1338766Speter return; 1339766Speter if (isnta(ap, "i")) { 1340766Speter error("argv's first argument must be an integer, not %s", nameof(ap)); 1341766Speter return; 1342766Speter } 134315934Smckusick al = argv->list_node.next; 134415934Smckusick ap = stklval(al->list_node.list, MOD|NOUSE); 134515934Smckusick if (ap == NLNIL) 1346766Speter return; 1347766Speter if (classify(ap) != TSTR) { 1348766Speter error("argv's second argument must be a string, not %s", nameof(ap)); 1349766Speter return; 1350766Speter } 135118467Sralph putop( PCC_CM , PCCT_INT ); 135218467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 135318467Sralph putop( PCC_CM , PCCT_INT ); 135418467Sralph putop( PCC_CALL , PCCT_INT ); 1355766Speter putdot( filename , line ); 1356766Speter return; 1357766Speter 1358766Speter case O_STLIM: 1359766Speter if (argc != 1) { 1360766Speter error("stlimit requires one argument"); 1361766Speter return; 1362766Speter } 136318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1364766Speter , "_STLIM" ); 136515934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 136615934Smckusick if (ap == NLNIL) 1367766Speter return; 1368766Speter if (isnta(ap, "i")) { 1369766Speter error("stlimit's argument must be an integer, not %s", nameof(ap)); 1370766Speter return; 1371766Speter } 137218467Sralph putop( PCC_CALL , PCCT_INT ); 1373766Speter putdot( filename , line ); 1374766Speter return; 1375766Speter 1376766Speter case O_REMOVE: 1377766Speter if (argc != 1) { 1378766Speter error("remove expects one argument"); 1379766Speter return; 1380766Speter } 138118467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1382766Speter , "_REMOVE" ); 138315934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 138415934Smckusick if (ap == NLNIL) 1385766Speter return; 1386766Speter if (classify(ap) != TSTR) { 1387766Speter error("remove's argument must be a string, not %s", nameof(ap)); 1388766Speter return; 1389766Speter } 139018467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 139118467Sralph putop( PCC_CM , PCCT_INT ); 139218467Sralph putop( PCC_CALL , PCCT_INT ); 1393766Speter putdot( filename , line ); 1394766Speter return; 1395766Speter 1396766Speter case O_LLIMIT: 1397766Speter if (argc != 2) { 1398766Speter error("linelimit expects two arguments"); 1399766Speter return; 1400766Speter } 140118467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1402766Speter , "_LLIMIT" ); 140315934Smckusick ap = stklval(argv->list_node.list, NOFLAGS|NOUSE); 140415934Smckusick if (ap == NLNIL) 1405766Speter return; 1406766Speter if (!text(ap)) { 1407766Speter error("linelimit's first argument must be a text file, not %s", nameof(ap)); 1408766Speter return; 1409766Speter } 141015934Smckusick al = argv->list_node.next; 141115934Smckusick ap = stkrval(al->list_node.list, NLNIL , (long) RREQ ); 141215934Smckusick if (ap == NLNIL) 1413766Speter return; 1414766Speter if (isnta(ap, "i")) { 1415766Speter error("linelimit's second argument must be an integer, not %s", nameof(ap)); 1416766Speter return; 1417766Speter } 141818467Sralph putop( PCC_CM , PCCT_INT ); 141918467Sralph putop( PCC_CALL , PCCT_INT ); 1420766Speter putdot( filename , line ); 1421766Speter return; 1422766Speter case O_PAGE: 1423766Speter if (argc != 1) { 1424766Speter error("page expects one argument"); 1425766Speter return; 1426766Speter } 142718467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 142818467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1429766Speter , "_UNIT" ); 143015934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 143115934Smckusick if (ap == NLNIL) 1432766Speter return; 1433766Speter if (!text(ap)) { 1434766Speter error("Argument to page must be a text file, not %s", nameof(ap)); 1435766Speter return; 1436766Speter } 143718467Sralph putop( PCC_CALL , PCCT_INT ); 143818467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 1439766Speter putdot( filename , line ); 1440766Speter if ( opt( 't' ) ) { 144118467Sralph putleaf( PCC_ICON , 0 , 0 144218467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1443766Speter , "_PAGE" ); 144418467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 1445766Speter } else { 144618467Sralph putleaf( PCC_ICON , 0 , 0 144718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1448766Speter , "_fputc" ); 144918467Sralph putleaf( PCC_ICON , '\f' , 0 , (int) PCCT_CHAR , (char *) 0 ); 145018467Sralph putleaf( PCC_ICON , 0 , 0 145118467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1452766Speter , "_ACTFILE" ); 145318467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 145418467Sralph putop( PCC_CALL , PCCT_INT ); 145518467Sralph putop( PCC_CM , PCCT_INT ); 1456766Speter } 145718467Sralph putop( PCC_CALL , PCCT_INT ); 1458766Speter putdot( filename , line ); 1459766Speter return; 1460766Speter 14617928Smckusick case O_ASRT: 14627928Smckusick if (!opt('t')) 14637928Smckusick return; 14647928Smckusick if (argc == 0 || argc > 2) { 14657928Smckusick error("Assert expects one or two arguments"); 14667928Smckusick return; 14677928Smckusick } 14689139Smckusick if (argc == 2) 14699139Smckusick cmd = "_ASRTS"; 14709139Smckusick else 14719139Smckusick cmd = "_ASRT"; 147218467Sralph putleaf( PCC_ICON , 0 , 0 147318467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , cmd ); 147415934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 147515934Smckusick if (ap == NLNIL) 14767928Smckusick return; 14777928Smckusick if (isnta(ap, "b")) 14787928Smckusick error("Assert expression must be Boolean, not %ss", nameof(ap)); 14797928Smckusick if (argc == 2) { 14807928Smckusick /* 14817928Smckusick * Optional second argument is a string specifying 14827928Smckusick * why the assertion failed. 14837928Smckusick */ 148415934Smckusick al = argv->list_node.next; 148515934Smckusick al = (struct tnode *) stkrval(al->list_node.list, NLNIL , (long) RREQ ); 148615934Smckusick if (al == TR_NIL) 14877928Smckusick return; 148815934Smckusick if (classify((struct nl *) al) != TSTR) { 148915934Smckusick error("Second argument to assert must be a string, not %s", nameof((struct nl *) al)); 14907928Smckusick return; 14917928Smckusick } 149218467Sralph putop( PCC_CM , PCCT_INT ); 14937928Smckusick } 149418467Sralph putop( PCC_CALL , PCCT_INT ); 14957928Smckusick putdot( filename , line ); 14967928Smckusick return; 14977928Smckusick 1498766Speter case O_PACK: 1499766Speter if (argc != 3) { 1500766Speter error("pack expects three arguments"); 1501766Speter return; 1502766Speter } 150318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1504766Speter , "_PACK" ); 1505766Speter pu = "pack(a,i,z)"; 150615934Smckusick pua = (al = argv)->list_node.list; 150715934Smckusick pui = (al = al->list_node.next)->list_node.list; 150815934Smckusick puz = (al = al->list_node.next)->list_node.list; 1509766Speter goto packunp; 1510766Speter case O_UNPACK: 1511766Speter if (argc != 3) { 1512766Speter error("unpack expects three arguments"); 1513766Speter return; 1514766Speter } 151518467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1516766Speter , "_UNPACK" ); 1517766Speter pu = "unpack(z,a,i)"; 151815934Smckusick puz = (al = argv)->list_node.list; 151915934Smckusick pua = (al = al->list_node.next)->list_node.list; 152015934Smckusick pui = (al = al->list_node.next)->list_node.list; 1521766Speter packunp: 152215934Smckusick ap = stkrval(pui, NLNIL , (long) RREQ ); 1523766Speter if (ap == NIL) 1524766Speter return; 1525766Speter ap = stklval(pua, op == O_PACK ? NOFLAGS : MOD|NOUSE); 1526766Speter if (ap == NIL) 1527766Speter return; 1528766Speter if (ap->class != ARRAY) { 1529766Speter error("%s requires a to be an unpacked array, not %s", pu, nameof(ap)); 1530766Speter return; 1531766Speter } 153218467Sralph putop( PCC_CM , PCCT_INT ); 153315934Smckusick al = (struct tnode *) stklval(puz, op == O_UNPACK ? NOFLAGS : MOD|NOUSE); 153415934Smckusick if (((struct nl *) al)->class != ARRAY) { 1535766Speter error("%s requires z to be a packed array, not %s", pu, nameof(ap)); 1536766Speter return; 1537766Speter } 153815934Smckusick if (((struct nl *) al)->type == NIL || 153915934Smckusick ((struct nl *) ap)->type == NIL) 1540766Speter return; 154115934Smckusick if (((struct nl *) al)->type != ((struct nl *) ap)->type) { 1542766Speter error("%s requires a and z to be arrays of the same type", pu, nameof(ap)); 1543766Speter return; 1544766Speter } 154518467Sralph putop( PCC_CM , PCCT_INT ); 154615934Smckusick k = width((struct nl *) al); 1547766Speter itemwidth = width(ap->type); 1548766Speter ap = ap->chain; 154915934Smckusick al = ((struct tnode *) ((struct nl *) al)->chain); 155015934Smckusick if (ap->chain != NIL || ((struct nl *) al)->chain != NIL) { 1551766Speter error("%s requires a and z to be single dimension arrays", pu); 1552766Speter return; 1553766Speter } 1554766Speter if (ap == NIL || al == NIL) 1555766Speter return; 1556766Speter /* 1557766Speter * al is the range for z i.e. u..v 1558766Speter * ap is the range for a i.e. m..n 1559766Speter * i will be n-m+1 1560766Speter * j will be v-u+1 1561766Speter */ 1562766Speter i = ap->range[1] - ap->range[0] + 1; 156315934Smckusick j = ((struct nl *) al)->range[1] - 156415934Smckusick ((struct nl *) al)->range[0] + 1; 1565766Speter if (i < j) { 156615934Smckusick error("%s cannot have more elements in a (%d) than in z (%d)", pu, (char *) j, (char *) i); 1567766Speter return; 1568766Speter } 1569766Speter /* 1570766Speter * get n-m-(v-u) and m for the interpreter 1571766Speter */ 1572766Speter i -= j; 1573766Speter j = ap->range[0]; 157418467Sralph putleaf( PCC_ICON , itemwidth , 0 , PCCT_INT , (char *) 0 ); 157518467Sralph putop( PCC_CM , PCCT_INT ); 157618467Sralph putleaf( PCC_ICON , j , 0 , PCCT_INT , (char *) 0 ); 157718467Sralph putop( PCC_CM , PCCT_INT ); 157818467Sralph putleaf( PCC_ICON , i , 0 , PCCT_INT , (char *) 0 ); 157918467Sralph putop( PCC_CM , PCCT_INT ); 158018467Sralph putleaf( PCC_ICON , k , 0 , PCCT_INT , (char *) 0 ); 158118467Sralph putop( PCC_CM , PCCT_INT ); 158218467Sralph putop( PCC_CALL , PCCT_INT ); 1583766Speter putdot( filename , line ); 1584766Speter return; 1585766Speter case 0: 15867928Smckusick error("%s is an unimplemented extension", p->symbol); 1587766Speter return; 1588766Speter 1589766Speter default: 1590766Speter panic("proc case"); 1591766Speter } 1592766Speter } 1593766Speter #endif PC 1594