1*22216Sdist /* 2*22216Sdist * Copyright (c) 1980 Regents of the University of California. 3*22216Sdist * All rights reserved. The Berkeley software License Agreement 4*22216Sdist * specifies the terms and conditions for redistribution. 5*22216Sdist */ 6766Speter 715934Smckusick #ifndef lint 8*22216Sdist static char sccsid[] = "@(#)pcproc.c 5.1 (Berkeley) 06/05/85"; 9*22216Sdist #endif not lint 10766Speter 11766Speter #include "whoami.h" 12766Speter #ifdef PC 13766Speter /* 14766Speter * and to the end of the file 15766Speter */ 16766Speter #include "0.h" 17766Speter #include "tree.h" 1810372Speter #include "objfmt.h" 19766Speter #include "opcode.h" 2010372Speter #include "pc.h" 2118467Sralph #include <pcc.h> 2211333Speter #include "tmps.h" 2315934Smckusick #include "tree_ty.h" 24766Speter 25766Speter /* 2611883Smckusick * The constant EXPOSIZE specifies the number of digits in the exponent 2711883Smckusick * of real numbers. 2811883Smckusick * 299229Smckusick * The constant REALSPC defines the amount of forced padding preceeding 309229Smckusick * real numbers when they are printed. If REALSPC == 0, then no padding 319229Smckusick * is added, REALSPC == 1 adds one extra blank irregardless of the width 329229Smckusick * specified by the user. 339229Smckusick * 349229Smckusick * N.B. - Values greater than one require program mods. 359229Smckusick */ 3611883Smckusick #define EXPOSIZE 2 3711883Smckusick #define REALSPC 0 389229Smckusick 399229Smckusick /* 40766Speter * The following array is used to determine which classes may be read 41766Speter * from textfiles. It is indexed by the return value from classify. 42766Speter */ 43766Speter #define rdops(x) rdxxxx[(x)-(TFIRST)] 44766Speter 45766Speter int rdxxxx[] = { 46766Speter 0, /* -7 file types */ 47766Speter 0, /* -6 record types */ 48766Speter 0, /* -5 array types */ 49766Speter O_READE, /* -4 scalar types */ 50766Speter 0, /* -3 pointer types */ 51766Speter 0, /* -2 set types */ 52766Speter 0, /* -1 string types */ 53766Speter 0, /* 0 nil, no type */ 54766Speter O_READE, /* 1 boolean */ 55766Speter O_READC, /* 2 character */ 56766Speter O_READ4, /* 3 integer */ 57766Speter O_READ8 /* 4 real */ 58766Speter }; 59766Speter 60766Speter /* 61766Speter * Proc handles procedure calls. 62766Speter * Non-builtin procedures are "buck-passed" to func (with a flag 63766Speter * indicating that they are actually procedures. 64766Speter * builtin procedures are handled here. 65766Speter */ 66766Speter pcproc(r) 6715934Smckusick struct tnode *r; /* T_PCALL */ 68766Speter { 69766Speter register struct nl *p; 7015934Smckusick register struct tnode *alv, *al; 7115934Smckusick register op; 72766Speter struct nl *filetype, *ap; 7315934Smckusick int argc, typ, fmtspec, strfmt; 7415934Smckusick struct tnode *argv, *file; 757967Smckusick char fmt, format[20], *strptr, *cmd; 7615934Smckusick int prec, field, strnglen, fmtstart; 7715934Smckusick char *pu; 7815934Smckusick struct tnode *pua, *pui, *puz; 79766Speter int i, j, k; 80766Speter int itemwidth; 813833Speter char *readname; 823833Speter struct nl *tempnlp; 833833Speter long readtype; 843833Speter struct tmps soffset; 8515935Smckusick bool soffset_flag; 86766Speter 87766Speter #define CONPREC 4 88766Speter #define VARPREC 8 89766Speter #define CONWIDTH 1 90766Speter #define VARWIDTH 2 91766Speter #define SKIP 16 92766Speter 93766Speter /* 94766Speter * Verify that the name is 95766Speter * defined and is that of a 96766Speter * procedure. 97766Speter */ 9815934Smckusick p = lookup(r->pcall_node.proc_id); 9915934Smckusick if (p == NLNIL) { 10015934Smckusick rvlist(r->pcall_node.arg); 101766Speter return; 102766Speter } 1031197Speter if (p->class != PROC && p->class != FPROC) { 104766Speter error("Can't call %s, its %s not a procedure", p->symbol, classes[p->class]); 10515934Smckusick rvlist(r->pcall_node.arg); 106766Speter return; 107766Speter } 10815934Smckusick argv = r->pcall_node.arg; 109766Speter 110766Speter /* 111766Speter * Call handles user defined 112766Speter * procedures and functions. 113766Speter */ 114766Speter if (bn != 0) { 11515934Smckusick (void) call(p, argv, PROC, bn); 116766Speter return; 117766Speter } 118766Speter 119766Speter /* 120766Speter * Call to built-in procedure. 121766Speter * Count the arguments. 122766Speter */ 123766Speter argc = 0; 12415934Smckusick for (al = argv; al != TR_NIL; al = al->list_node.next) 125766Speter argc++; 126766Speter 127766Speter /* 128766Speter * Switch on the operator 129766Speter * associated with the built-in 130766Speter * procedure in the namelist 131766Speter */ 132766Speter op = p->value[0] &~ NSTAND; 133766Speter if (opt('s') && (p->value[0] & NSTAND)) { 134766Speter standard(); 135766Speter error("%s is a nonstandard procedure", p->symbol); 136766Speter } 137766Speter switch (op) { 138766Speter 139766Speter case O_ABORT: 140766Speter if (argc != 0) 141766Speter error("null takes no arguments"); 142766Speter return; 143766Speter 144766Speter case O_FLUSH: 145766Speter if (argc == 0) { 14618467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" ); 14718467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 148766Speter putdot( filename , line ); 149766Speter return; 150766Speter } 151766Speter if (argc != 1) { 152766Speter error("flush takes at most one argument"); 153766Speter return; 154766Speter } 15518467Sralph putleaf( PCC_ICON , 0 , 0 15618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 157766Speter , "_FLUSH" ); 15815934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 15915934Smckusick if (ap == NLNIL) 160766Speter return; 161766Speter if (ap->class != FILET) { 162766Speter error("flush's argument must be a file, not %s", nameof(ap)); 163766Speter return; 164766Speter } 16518467Sralph putop( PCC_CALL , PCCT_INT ); 166766Speter putdot( filename , line ); 167766Speter return; 168766Speter 169766Speter case O_MESSAGE: 170766Speter case O_WRITEF: 171766Speter case O_WRITLN: 172766Speter /* 173766Speter * Set up default file "output"'s type 174766Speter */ 175766Speter file = NIL; 176766Speter filetype = nl+T1CHAR; 177766Speter /* 178766Speter * Determine the file implied 179766Speter * for the write and generate 180766Speter * code to make it the active file. 181766Speter */ 182766Speter if (op == O_MESSAGE) { 183766Speter /* 184766Speter * For message, all that matters 185766Speter * is that the filetype is 186766Speter * a character file. 187766Speter * Thus "output" will suit us fine. 188766Speter */ 18918467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" ); 19018467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 191766Speter putdot( filename , line ); 19215934Smckusick putRV( (char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 19318467Sralph PCCTM_PTR|PCCT_STRTY ); 19418467Sralph putLV( "__err" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 19518467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 196766Speter putdot( filename , line ); 19715934Smckusick } else if (argv != TR_NIL && (al = argv->list_node.list)->tag != 19815934Smckusick T_WEXP) { 199766Speter /* 200766Speter * If there is a first argument which has 201766Speter * no write widths, then it is potentially 202766Speter * a file name. 203766Speter */ 204766Speter codeoff(); 20515934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 206766Speter codeon(); 20715934Smckusick if (ap == NLNIL) 20815934Smckusick argv = argv->list_node.next; 209766Speter if (ap != NIL && ap->class == FILET) { 210766Speter /* 211766Speter * Got "write(f, ...", make 212766Speter * f the active file, and save 213766Speter * it and its type for use in 214766Speter * processing the rest of the 215766Speter * arguments to write. 216766Speter */ 21715934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 21818467Sralph PCCTM_PTR|PCCT_STRTY ); 21918467Sralph putleaf( PCC_ICON , 0 , 0 22018467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 221766Speter , "_UNIT" ); 22215934Smckusick file = argv->list_node.list; 223766Speter filetype = ap->type; 22415934Smckusick (void) stklval(argv->list_node.list, NOFLAGS); 22518467Sralph putop( PCC_CALL , PCCT_INT ); 22618467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 227766Speter putdot( filename , line ); 228766Speter /* 229766Speter * Skip over the first argument 230766Speter */ 23115934Smckusick argv = argv->list_node.next; 232766Speter argc--; 233766Speter } else { 234766Speter /* 235766Speter * Set up for writing on 236766Speter * standard output. 237766Speter */ 23815934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , 23918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 2403833Speter putLV( "_output" , 0 , 0 , NGLOBAL , 24118467Sralph PCCTM_PTR|PCCT_STRTY ); 24218467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 243766Speter putdot( filename , line ); 2447954Speter output->nl_flags |= NUSED; 245766Speter } 246766Speter } else { 24715934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 24818467Sralph PCCTM_PTR|PCCT_STRTY ); 24918467Sralph putLV( "_output" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 25018467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 251766Speter putdot( filename , line ); 2527954Speter output->nl_flags |= NUSED; 253766Speter } 254766Speter /* 255766Speter * Loop and process each 256766Speter * of the arguments. 257766Speter */ 25815934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 25915935Smckusick soffset_flag = FALSE; 260766Speter /* 261766Speter * fmtspec indicates the type (CONstant or VARiable) 262766Speter * and number (none, WIDTH, and/or PRECision) 263766Speter * of the fields in the printf format for this 264766Speter * output variable. 265766Speter * fmt is the format output indicator (D, E, F, O, X, S) 266766Speter * fmtstart = 0 for leading blank; = 1 for no blank 267766Speter */ 268766Speter fmtspec = NIL; 269766Speter fmt = 'D'; 270766Speter fmtstart = 1; 27115934Smckusick al = argv->list_node.list; 272766Speter if (al == NIL) 273766Speter continue; 27415934Smckusick if (al->tag == T_WEXP) 27515934Smckusick alv = al->wexpr_node.expr1; 276766Speter else 277766Speter alv = al; 27815934Smckusick if (alv == TR_NIL) 279766Speter continue; 280766Speter codeoff(); 28115934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 282766Speter codeon(); 28315934Smckusick if (ap == NLNIL) 284766Speter continue; 285766Speter typ = classify(ap); 28615934Smckusick if (al->tag == T_WEXP) { 287766Speter /* 288766Speter * Handle width expressions. 289766Speter * The basic game here is that width 290766Speter * expressions get evaluated. If they 291766Speter * are constant, the value is placed 292766Speter * directly in the format string. 293766Speter * Otherwise the value is pushed onto 294766Speter * the stack and an indirection is 295766Speter * put into the format string. 296766Speter */ 29715934Smckusick if (al->wexpr_node.expr3 == 29815934Smckusick (struct tnode *) OCT) 299766Speter fmt = 'O'; 30015934Smckusick else if (al->wexpr_node.expr3 == 30115934Smckusick (struct tnode *) HEX) 302766Speter fmt = 'X'; 30315934Smckusick else if (al->wexpr_node.expr3 != TR_NIL) { 304766Speter /* 305766Speter * Evaluate second format spec 306766Speter */ 30715934Smckusick if ( constval(al->wexpr_node.expr3) 308766Speter && isa( con.ctype , "i" ) ) { 309766Speter fmtspec += CONPREC; 310766Speter prec = con.crval; 311766Speter } else { 312766Speter fmtspec += VARPREC; 313766Speter } 314766Speter fmt = 'f'; 315766Speter switch ( typ ) { 316766Speter case TINT: 317766Speter if ( opt( 's' ) ) { 318766Speter standard(); 319766Speter error("Writing %ss with two write widths is non-standard", clnames[typ]); 320766Speter } 321766Speter /* and fall through */ 322766Speter case TDOUBLE: 323766Speter break; 324766Speter default: 325766Speter error("Cannot write %ss with two write widths", clnames[typ]); 326766Speter continue; 327766Speter } 328766Speter } 329766Speter /* 330766Speter * Evaluate first format spec 331766Speter */ 33215934Smckusick if (al->wexpr_node.expr2 != TR_NIL) { 33315934Smckusick if ( constval(al->wexpr_node.expr2) 334766Speter && isa( con.ctype , "i" ) ) { 335766Speter fmtspec += CONWIDTH; 336766Speter field = con.crval; 337766Speter } else { 338766Speter fmtspec += VARWIDTH; 339766Speter } 340766Speter } 341766Speter if ((fmtspec & CONPREC) && prec < 0 || 342766Speter (fmtspec & CONWIDTH) && field < 0) { 343766Speter error("Negative widths are not allowed"); 344766Speter continue; 345766Speter } 3463180Smckusic if ( opt('s') && 3473180Smckusic ((fmtspec & CONPREC) && prec == 0 || 3483180Smckusic (fmtspec & CONWIDTH) && field == 0)) { 3493180Smckusic standard(); 3503180Smckusic error("Zero widths are non-standard"); 3513180Smckusic } 352766Speter } 353766Speter if (filetype != nl+T1CHAR) { 354766Speter if (fmt == 'O' || fmt == 'X') { 355766Speter error("Oct/hex allowed only on text files"); 356766Speter continue; 357766Speter } 358766Speter if (fmtspec) { 359766Speter error("Write widths allowed only on text files"); 360766Speter continue; 361766Speter } 362766Speter /* 363766Speter * Generalized write, i.e. 364766Speter * to a non-textfile. 365766Speter */ 36618467Sralph putleaf( PCC_ICON , 0 , 0 36718467Sralph , (int) (PCCM_ADDTYPE( 36818467Sralph PCCM_ADDTYPE( 36918467Sralph PCCM_ADDTYPE( p2type( filetype ) 37018467Sralph , PCCTM_PTR ) 37118467Sralph , PCCTM_FTN ) 37218467Sralph , PCCTM_PTR )) 373766Speter , "_FNIL" ); 37415934Smckusick (void) stklval(file, NOFLAGS); 37518467Sralph putop( PCC_CALL 37618467Sralph , PCCM_ADDTYPE( p2type( filetype ) , PCCTM_PTR ) ); 37718467Sralph putop( PCCOM_UNARY PCC_MUL , p2type( filetype ) ); 378766Speter /* 379766Speter * file^ := ... 380766Speter */ 381766Speter switch ( classify( filetype ) ) { 382766Speter case TBOOL: 383766Speter case TCHAR: 384766Speter case TINT: 385766Speter case TSCAL: 3864589Speter precheck( filetype , "_RANG4" , "_RSNG4" ); 387766Speter /* and fall through */ 388766Speter case TDOUBLE: 389766Speter case TPTR: 39015934Smckusick ap = rvalue( argv->list_node.list , filetype , RREQ ); 391766Speter break; 392766Speter default: 39315934Smckusick ap = rvalue( argv->list_node.list , filetype , LREQ ); 394766Speter break; 395766Speter } 396766Speter if (ap == NIL) 397766Speter continue; 39815934Smckusick if (incompat(ap, filetype, argv->list_node.list)) { 399766Speter cerror("Type mismatch in write to non-text file"); 400766Speter continue; 401766Speter } 402766Speter switch ( classify( filetype ) ) { 403766Speter case TBOOL: 404766Speter case TCHAR: 405766Speter case TINT: 406766Speter case TSCAL: 40710373Speter postcheck(filetype, ap); 40810373Speter sconv(p2type(ap), p2type(filetype)); 409766Speter /* and fall through */ 410766Speter case TDOUBLE: 411766Speter case TPTR: 41218467Sralph putop( PCC_ASSIGN , p2type( filetype ) ); 413766Speter putdot( filename , line ); 414766Speter break; 415766Speter default: 41618467Sralph putstrop(PCC_STASG, 41718467Sralph PCCM_ADDTYPE(p2type(filetype), 41818467Sralph PCCTM_PTR), 41915934Smckusick (int) lwidth(filetype), 42011856Speter align(filetype)); 421766Speter putdot( filename , line ); 422766Speter break; 423766Speter } 424766Speter /* 425766Speter * put(file) 426766Speter */ 42718467Sralph putleaf( PCC_ICON , 0 , 0 42818467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 429766Speter , "_PUT" ); 43015934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 43118467Sralph PCCTM_PTR|PCCT_STRTY ); 43218467Sralph putop( PCC_CALL , PCCT_INT ); 433766Speter putdot( filename , line ); 434766Speter continue; 435766Speter } 436766Speter /* 437766Speter * Write to a textfile 438766Speter * 439766Speter * Evaluate the expression 440766Speter * to be written. 441766Speter */ 442766Speter if (fmt == 'O' || fmt == 'X') { 443766Speter if (opt('s')) { 444766Speter standard(); 445766Speter error("Oct and hex are non-standard"); 446766Speter } 447766Speter if (typ == TSTR || typ == TDOUBLE) { 448766Speter error("Can't write %ss with oct/hex", clnames[typ]); 449766Speter continue; 450766Speter } 451766Speter if (typ == TCHAR || typ == TBOOL) 452766Speter typ = TINT; 453766Speter } 454766Speter /* 455766Speter * If there is no format specified by the programmer, 456766Speter * implement the default. 457766Speter */ 458766Speter switch (typ) { 4596540Smckusick case TPTR: 4606540Smckusick warning(); 4616540Smckusick if (opt('s')) { 4626540Smckusick standard(); 4636540Smckusick } 4646540Smckusick error("Writing %ss to text files is non-standard", 4656540Smckusick clnames[typ]); 4666540Smckusick /* and fall through */ 467766Speter case TINT: 468766Speter if (fmt == 'f') { 469766Speter typ = TDOUBLE; 470766Speter goto tdouble; 471766Speter } 472766Speter if (fmtspec == NIL) { 473766Speter if (fmt == 'D') 474766Speter field = 10; 475766Speter else if (fmt == 'X') 476766Speter field = 8; 477766Speter else if (fmt == 'O') 478766Speter field = 11; 479766Speter else 480766Speter panic("fmt1"); 481766Speter fmtspec = CONWIDTH; 482766Speter } 483766Speter break; 484766Speter case TCHAR: 485766Speter tchar: 486766Speter fmt = 'c'; 487766Speter break; 488766Speter case TSCAL: 4891629Speter warning(); 490766Speter if (opt('s')) { 491766Speter standard(); 492766Speter } 4936540Smckusick error("Writing %ss to text files is non-standard", 4946540Smckusick clnames[typ]); 495766Speter case TBOOL: 496766Speter fmt = 's'; 497766Speter break; 498766Speter case TDOUBLE: 499766Speter tdouble: 500766Speter switch (fmtspec) { 501766Speter case NIL: 50211883Smckusick field = 14 + (5 + EXPOSIZE); 50311883Smckusick prec = field - (5 + EXPOSIZE); 5043225Smckusic fmt = 'e'; 505766Speter fmtspec = CONWIDTH + CONPREC; 506766Speter break; 507766Speter case CONWIDTH: 5089229Smckusick field -= REALSPC; 5099229Smckusick if (field < 1) 510766Speter field = 1; 51111883Smckusick prec = field - (5 + EXPOSIZE); 512766Speter if (prec < 1) 513766Speter prec = 1; 514766Speter fmtspec += CONPREC; 5153225Smckusic fmt = 'e'; 516766Speter break; 517766Speter case VARWIDTH: 518766Speter fmtspec += VARPREC; 5193225Smckusic fmt = 'e'; 520766Speter break; 521766Speter case CONWIDTH + CONPREC: 522766Speter case CONWIDTH + VARPREC: 5239229Smckusick field -= REALSPC; 5249229Smckusick if (field < 1) 525766Speter field = 1; 526766Speter } 527766Speter format[0] = ' '; 5289229Smckusick fmtstart = 1 - REALSPC; 529766Speter break; 530766Speter case TSTR: 53115934Smckusick (void) constval( alv ); 532766Speter switch ( classify( con.ctype ) ) { 533766Speter case TCHAR: 534766Speter typ = TCHAR; 535766Speter goto tchar; 536766Speter case TSTR: 537766Speter strptr = con.cpval; 538766Speter for (strnglen = 0; *strptr++; strnglen++) /* void */; 539766Speter strptr = con.cpval; 540766Speter break; 541766Speter default: 542766Speter strnglen = width(ap); 543766Speter break; 544766Speter } 545766Speter fmt = 's'; 546766Speter strfmt = fmtspec; 547766Speter if (fmtspec == NIL) { 548766Speter fmtspec = SKIP; 549766Speter break; 550766Speter } 551766Speter if (fmtspec & CONWIDTH) { 552766Speter if (field <= strnglen) 553766Speter fmtspec = SKIP; 554766Speter else 555766Speter field -= strnglen; 556766Speter } 557766Speter break; 558766Speter default: 559766Speter error("Can't write %ss to a text file", clnames[typ]); 560766Speter continue; 561766Speter } 562766Speter /* 563766Speter * Generate the format string 564766Speter */ 565766Speter switch (fmtspec) { 566766Speter default: 567766Speter panic("fmt2"); 568766Speter case NIL: 569766Speter if (fmt == 'c') { 570766Speter if ( opt( 't' ) ) { 57118467Sralph putleaf( PCC_ICON , 0 , 0 57218467Sralph , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR ) 573766Speter , "_WRITEC" ); 57415934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 57518467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 57615934Smckusick (void) stkrval( alv , NLNIL , (long) RREQ ); 57718467Sralph putop( PCC_CM , PCCT_INT ); 578766Speter } else { 57918467Sralph putleaf( PCC_ICON , 0 , 0 58018467Sralph , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR ) 581766Speter , "_fputc" ); 58215934Smckusick (void) stkrval( alv , NLNIL , 58315934Smckusick (long) RREQ ); 584766Speter } 58518467Sralph putleaf( PCC_ICON , 0 , 0 58618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 587766Speter , "_ACTFILE" ); 58815934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , 58918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 59018467Sralph putop( PCC_CALL , PCCT_INT ); 59118467Sralph putop( PCC_CM , PCCT_INT ); 59218467Sralph putop( PCC_CALL , PCCT_INT ); 593766Speter putdot( filename , line ); 594766Speter } else { 595766Speter sprintf(&format[1], "%%%c", fmt); 596766Speter goto fmtgen; 597766Speter } 598766Speter case SKIP: 599766Speter break; 600766Speter case CONWIDTH: 601766Speter sprintf(&format[1], "%%%1D%c", field, fmt); 602766Speter goto fmtgen; 603766Speter case VARWIDTH: 604766Speter sprintf(&format[1], "%%*%c", fmt); 605766Speter goto fmtgen; 606766Speter case CONWIDTH + CONPREC: 607766Speter sprintf(&format[1], "%%%1D.%1D%c", field, prec, fmt); 608766Speter goto fmtgen; 609766Speter case CONWIDTH + VARPREC: 610766Speter sprintf(&format[1], "%%%1D.*%c", field, fmt); 611766Speter goto fmtgen; 612766Speter case VARWIDTH + CONPREC: 613766Speter sprintf(&format[1], "%%*.%1D%c", prec, fmt); 614766Speter goto fmtgen; 615766Speter case VARWIDTH + VARPREC: 616766Speter sprintf(&format[1], "%%*.*%c", fmt); 617766Speter fmtgen: 618766Speter if ( opt( 't' ) ) { 61918467Sralph putleaf( PCC_ICON , 0 , 0 62018467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 621766Speter , "_WRITEF" ); 62215934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 62318467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 62418467Sralph putleaf( PCC_ICON , 0 , 0 62518467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 626766Speter , "_ACTFILE" ); 62715934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 62818467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 62918467Sralph putop( PCC_CALL , PCCT_INT ); 63018467Sralph putop( PCC_CM , PCCT_INT ); 631766Speter } else { 63218467Sralph putleaf( PCC_ICON , 0 , 0 63318467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 634766Speter , "_fprintf" ); 63518467Sralph putleaf( PCC_ICON , 0 , 0 63618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 637766Speter , "_ACTFILE" ); 63815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 63918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 64018467Sralph putop( PCC_CALL , PCCT_INT ); 641766Speter } 642766Speter putCONG( &format[ fmtstart ] 643766Speter , strlen( &format[ fmtstart ] ) 644766Speter , LREQ ); 64518467Sralph putop( PCC_CM , PCCT_INT ); 646766Speter if ( fmtspec & VARWIDTH ) { 647766Speter /* 648766Speter * either 649766Speter * ,(temp=width,MAX(temp,...)), 650766Speter * or 651766Speter * , MAX( width , ... ) , 652766Speter */ 65315934Smckusick if ( ( typ == TDOUBLE && 65415934Smckusick al->wexpr_node.expr3 == TR_NIL ) 655766Speter || typ == TSTR ) { 65615935Smckusick soffset_flag = TRUE; 6573225Smckusic soffset = sizes[cbn].curtmps; 65815934Smckusick tempnlp = tmpalloc((long) (sizeof(long)), 6593225Smckusic nl+T4INT, REGOK); 66015934Smckusick putRV((char *) 0 , cbn , 6613833Speter tempnlp -> value[ NL_OFFS ] , 66218467Sralph tempnlp -> extra_flags , PCCT_INT ); 66315934Smckusick ap = stkrval( al->wexpr_node.expr2 , 66415934Smckusick NLNIL , (long) RREQ ); 66518467Sralph putop( PCC_ASSIGN , PCCT_INT ); 66618467Sralph putleaf( PCC_ICON , 0 , 0 66718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 668766Speter , "_MAX" ); 66915934Smckusick putRV((char *) 0 , cbn , 6703833Speter tempnlp -> value[ NL_OFFS ] , 67118467Sralph tempnlp -> extra_flags , PCCT_INT ); 672766Speter } else { 673766Speter if (opt('t') 674766Speter || typ == TSTR || typ == TDOUBLE) { 67518467Sralph putleaf( PCC_ICON , 0 , 0 67618467Sralph ,PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT, PCCTM_PTR ) 677766Speter ,"_MAX" ); 678766Speter } 67915934Smckusick ap = stkrval( al->wexpr_node.expr2, 68015934Smckusick NLNIL , (long) RREQ ); 681766Speter } 68215934Smckusick if (ap == NLNIL) 683766Speter continue; 684766Speter if (isnta(ap,"i")) { 685766Speter error("First write width must be integer, not %s", nameof(ap)); 686766Speter continue; 687766Speter } 688766Speter switch ( typ ) { 689766Speter case TDOUBLE: 69018467Sralph putleaf( PCC_ICON , REALSPC , 0 , PCCT_INT , (char *) 0 ); 69118467Sralph putop( PCC_CM , PCCT_INT ); 69218467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 69318467Sralph putop( PCC_CM , PCCT_INT ); 69418467Sralph putop( PCC_CALL , PCCT_INT ); 69515934Smckusick if ( al->wexpr_node.expr3 == TR_NIL ) { 696766Speter /* 697766Speter * finish up the comma op 698766Speter */ 69918467Sralph putop( PCC_COMOP , PCCT_INT ); 700766Speter fmtspec &= ~VARPREC; 70118467Sralph putop( PCC_CM , PCCT_INT ); 70218467Sralph putleaf( PCC_ICON , 0 , 0 70318467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 704766Speter , "_MAX" ); 70515934Smckusick putRV((char *) 0 , cbn , 7063833Speter tempnlp -> value[ NL_OFFS ] , 7073833Speter tempnlp -> extra_flags , 70818467Sralph PCCT_INT ); 70918467Sralph putleaf( PCC_ICON , 71011883Smckusick 5 + EXPOSIZE + REALSPC , 71118467Sralph 0 , PCCT_INT , (char *) 0 ); 71218467Sralph putop( PCC_CM , PCCT_INT ); 71318467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 71418467Sralph putop( PCC_CM , PCCT_INT ); 71518467Sralph putop( PCC_CALL , PCCT_INT ); 716766Speter } 71718467Sralph putop( PCC_CM , PCCT_INT ); 718766Speter break; 719766Speter case TSTR: 72018467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 72118467Sralph putop( PCC_CM , PCCT_INT ); 72218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 72318467Sralph putop( PCC_CM , PCCT_INT ); 72418467Sralph putop( PCC_CALL , PCCT_INT ); 72518467Sralph putop( PCC_COMOP , PCCT_INT ); 72618467Sralph putop( PCC_CM , PCCT_INT ); 727766Speter break; 728766Speter default: 729766Speter if (opt('t')) { 73018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 73118467Sralph putop( PCC_CM , PCCT_INT ); 73218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 73318467Sralph putop( PCC_CM , PCCT_INT ); 73418467Sralph putop( PCC_CALL , PCCT_INT ); 735766Speter } 73618467Sralph putop( PCC_CM , PCCT_INT ); 737766Speter break; 738766Speter } 739766Speter } 740766Speter /* 741766Speter * If there is a variable precision, 742766Speter * evaluate it 743766Speter */ 744766Speter if (fmtspec & VARPREC) { 745766Speter if (opt('t')) { 74618467Sralph putleaf( PCC_ICON , 0 , 0 74718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 748766Speter , "_MAX" ); 749766Speter } 75015934Smckusick ap = stkrval( al->wexpr_node.expr3 , 75115934Smckusick NLNIL , (long) RREQ ); 752766Speter if (ap == NIL) 753766Speter continue; 754766Speter if (isnta(ap,"i")) { 755766Speter error("Second write width must be integer, not %s", nameof(ap)); 756766Speter continue; 757766Speter } 758766Speter if (opt('t')) { 75918467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 76018467Sralph putop( PCC_CM , PCCT_INT ); 76118467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 76218467Sralph putop( PCC_CM , PCCT_INT ); 76318467Sralph putop( PCC_CALL , PCCT_INT ); 764766Speter } 76518467Sralph putop( PCC_CM , PCCT_INT ); 766766Speter } 767766Speter /* 768766Speter * evaluate the thing we want printed. 769766Speter */ 770766Speter switch ( typ ) { 7716540Smckusick case TPTR: 772766Speter case TCHAR: 773766Speter case TINT: 77415934Smckusick (void) stkrval( alv , NLNIL , (long) RREQ ); 77518467Sralph putop( PCC_CM , PCCT_INT ); 776766Speter break; 777766Speter case TDOUBLE: 77815934Smckusick ap = stkrval( alv , NLNIL , (long) RREQ ); 77910373Speter if (isnta(ap, "d")) { 78018467Sralph sconv(p2type(ap), PCCT_DOUBLE); 781766Speter } 78218467Sralph putop( PCC_CM , PCCT_INT ); 783766Speter break; 784766Speter case TSCAL: 785766Speter case TBOOL: 78618467Sralph putleaf( PCC_ICON , 0 , 0 78718467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 788766Speter , "_NAM" ); 78915934Smckusick ap = stkrval( alv , NLNIL , (long) RREQ ); 790766Speter sprintf( format , PREFIXFORMAT , LABELPREFIX 791766Speter , listnames( ap ) ); 79218467Sralph putleaf( PCC_ICON , 0 , 0 , 79318467Sralph (int) (PCCTM_PTR | PCCT_CHAR), format ); 79418467Sralph putop( PCC_CM , PCCT_INT ); 79518467Sralph putop( PCC_CALL , PCCT_INT ); 79618467Sralph putop( PCC_CM , PCCT_INT ); 797766Speter break; 798766Speter case TSTR: 799766Speter putCONG( "" , 0 , LREQ ); 80018467Sralph putop( PCC_CM , PCCT_INT ); 801766Speter break; 8026540Smckusick default: 8036540Smckusick panic("fmt3"); 8046540Smckusick break; 805766Speter } 80618467Sralph putop( PCC_CALL , PCCT_INT ); 807766Speter putdot( filename , line ); 808766Speter } 809766Speter /* 810766Speter * Write the string after its blank padding 811766Speter */ 812766Speter if (typ == TSTR ) { 813766Speter if ( opt( 't' ) ) { 81418467Sralph putleaf( PCC_ICON , 0 , 0 81518467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 816766Speter , "_WRITES" ); 81715934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 81818467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 81915934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 82018467Sralph putop( PCC_CM , PCCT_INT ); 821766Speter } else { 82218467Sralph putleaf( PCC_ICON , 0 , 0 82318467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 824766Speter , "_fwrite" ); 82515934Smckusick ap = stkrval(alv, NLNIL , (long) RREQ ); 826766Speter } 827766Speter if (strfmt & VARWIDTH) { 828766Speter /* 829766Speter * min, inline expanded as 830766Speter * temp < len ? temp : len 831766Speter */ 83215934Smckusick putRV((char *) 0 , cbn , 8333833Speter tempnlp -> value[ NL_OFFS ] , 83418467Sralph tempnlp -> extra_flags , PCCT_INT ); 83518467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 83618467Sralph putop( PCC_LT , PCCT_INT ); 83715934Smckusick putRV((char *) 0 , cbn , 8383833Speter tempnlp -> value[ NL_OFFS ] , 83918467Sralph tempnlp -> extra_flags , PCCT_INT ); 84018467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 84118467Sralph putop( PCC_COLON , PCCT_INT ); 84218467Sralph putop( PCC_QUEST , PCCT_INT ); 843766Speter } else { 844766Speter if ( ( fmtspec & SKIP ) 845766Speter && ( strfmt & CONWIDTH ) ) { 846766Speter strnglen = field; 847766Speter } 84818467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 849766Speter } 85018467Sralph putop( PCC_CM , PCCT_INT ); 85118467Sralph putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); 85218467Sralph putop( PCC_CM , PCCT_INT ); 85318467Sralph putleaf( PCC_ICON , 0 , 0 85418467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 855766Speter , "_ACTFILE" ); 85615934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 85718467Sralph PCCTM_PTR|PCCT_STRTY ); 85818467Sralph putop( PCC_CALL , PCCT_INT ); 85918467Sralph putop( PCC_CM , PCCT_INT ); 86018467Sralph putop( PCC_CALL , PCCT_INT ); 861766Speter putdot( filename , line ); 862766Speter } 86315935Smckusick if (soffset_flag) { 86415935Smckusick tmpfree(&soffset); 86515935Smckusick soffset_flag = FALSE; 86615935Smckusick } 867766Speter } 868766Speter /* 869766Speter * Done with arguments. 870766Speter * Handle writeln and 871766Speter * insufficent number of args. 872766Speter */ 873766Speter switch (p->value[0] &~ NSTAND) { 874766Speter case O_WRITEF: 875766Speter if (argc == 0) 876766Speter error("Write requires an argument"); 877766Speter break; 878766Speter case O_MESSAGE: 879766Speter if (argc == 0) 880766Speter error("Message requires an argument"); 881766Speter case O_WRITLN: 882766Speter if (filetype != nl+T1CHAR) 883766Speter error("Can't 'writeln' a non text file"); 884766Speter if ( opt( 't' ) ) { 88518467Sralph putleaf( PCC_ICON , 0 , 0 88618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 887766Speter , "_WRITLN" ); 88815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 88918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 890766Speter } else { 89118467Sralph putleaf( PCC_ICON , 0 , 0 89218467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 893766Speter , "_fputc" ); 89418467Sralph putleaf( PCC_ICON , '\n' , 0 , (int) PCCT_CHAR , (char *) 0 ); 89518467Sralph putleaf( PCC_ICON , 0 , 0 89618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 897766Speter , "_ACTFILE" ); 89815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , 89918467Sralph NLOCAL , PCCTM_PTR|PCCT_STRTY ); 90018467Sralph putop( PCC_CALL , PCCT_INT ); 90118467Sralph putop( PCC_CM , PCCT_INT ); 902766Speter } 90318467Sralph putop( PCC_CALL , PCCT_INT ); 904766Speter putdot( filename , line ); 905766Speter break; 906766Speter } 907766Speter return; 908766Speter 909766Speter case O_READ4: 910766Speter case O_READLN: 911766Speter /* 912766Speter * Set up default 913766Speter * file "input". 914766Speter */ 915766Speter file = NIL; 916766Speter filetype = nl+T1CHAR; 917766Speter /* 918766Speter * Determine the file implied 919766Speter * for the read and generate 920766Speter * code to make it the active file. 921766Speter */ 92215934Smckusick if (argv != TR_NIL) { 923766Speter codeoff(); 92415934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 925766Speter codeon(); 92615934Smckusick if (ap == NLNIL) 92715934Smckusick argv = argv->list_node.next; 92815934Smckusick if (ap != NLNIL && ap->class == FILET) { 929766Speter /* 930766Speter * Got "read(f, ...", make 931766Speter * f the active file, and save 932766Speter * it and its type for use in 933766Speter * processing the rest of the 934766Speter * arguments to read. 935766Speter */ 93615934Smckusick file = argv->list_node.list; 937766Speter filetype = ap->type; 93815934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 93918467Sralph PCCTM_PTR|PCCT_STRTY ); 94018467Sralph putleaf( PCC_ICON , 0 , 0 94118467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 942766Speter , "_UNIT" ); 94315934Smckusick (void) stklval(argv->list_node.list, NOFLAGS); 94418467Sralph putop( PCC_CALL , PCCT_INT ); 94518467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 946766Speter putdot( filename , line ); 94715934Smckusick argv = argv->list_node.next; 948766Speter argc--; 949766Speter } else { 950766Speter /* 951766Speter * Default is read from 952766Speter * standard input. 953766Speter */ 95415934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 95518467Sralph PCCTM_PTR|PCCT_STRTY ); 9563833Speter putLV( "_input" , 0 , 0 , NGLOBAL , 95718467Sralph PCCTM_PTR|PCCT_STRTY ); 95818467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 959766Speter putdot( filename , line ); 960766Speter input->nl_flags |= NUSED; 961766Speter } 962766Speter } else { 96315934Smckusick putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL , 96418467Sralph PCCTM_PTR|PCCT_STRTY ); 96518467Sralph putLV( "_input" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); 96618467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 967766Speter putdot( filename , line ); 968766Speter input->nl_flags |= NUSED; 969766Speter } 970766Speter /* 971766Speter * Loop and process each 972766Speter * of the arguments. 973766Speter */ 97415934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 975766Speter /* 976766Speter * Get the address of the target 977766Speter * on the stack. 978766Speter */ 97915934Smckusick al = argv->list_node.list; 98015934Smckusick if (al == TR_NIL) 981766Speter continue; 98215934Smckusick if (al->tag != T_VAR) { 983766Speter error("Arguments to %s must be variables, not expressions", p->symbol); 984766Speter continue; 985766Speter } 986766Speter codeoff(); 987766Speter ap = stklval(al, MOD|ASGN|NOUSE); 988766Speter codeon(); 98915934Smckusick if (ap == NLNIL) 990766Speter continue; 991766Speter if (filetype != nl+T1CHAR) { 992766Speter /* 993766Speter * Generalized read, i.e. 994766Speter * from a non-textfile. 995766Speter */ 99615934Smckusick if (incompat(filetype, ap, argv->list_node.list )) { 997766Speter error("Type mismatch in read from non-text file"); 998766Speter continue; 999766Speter } 1000766Speter /* 1001766Speter * var := file ^; 1002766Speter */ 1003766Speter ap = lvalue( al , MOD | ASGN | NOUSE , RREQ ); 1004766Speter if ( isa( ap , "bsci" ) ) { 1005766Speter precheck( ap , "_RANG4" , "_RSNG4" ); 1006766Speter } 100718467Sralph putleaf( PCC_ICON , 0 , 0 100818467Sralph , (int) (PCCM_ADDTYPE( 100918467Sralph PCCM_ADDTYPE( 101018467Sralph PCCM_ADDTYPE( 101118467Sralph p2type( filetype ) , PCCTM_PTR ) 101218467Sralph , PCCTM_FTN ) 101318467Sralph , PCCTM_PTR )) 1014766Speter , "_FNIL" ); 1015766Speter if (file != NIL) 101615934Smckusick (void) stklval(file, NOFLAGS); 1017766Speter else /* Magic */ 10183833Speter putRV( "_input" , 0 , 0 , NGLOBAL , 101918467Sralph PCCTM_PTR | PCCT_STRTY ); 102018467Sralph putop(PCC_CALL, PCCM_ADDTYPE(p2type(filetype), PCCTM_PTR)); 1021766Speter switch ( classify( filetype ) ) { 1022766Speter case TBOOL: 1023766Speter case TCHAR: 1024766Speter case TINT: 1025766Speter case TSCAL: 1026766Speter case TDOUBLE: 1027766Speter case TPTR: 102818467Sralph putop( PCCOM_UNARY PCC_MUL 1029766Speter , p2type( filetype ) ); 1030766Speter } 1031766Speter switch ( classify( filetype ) ) { 1032766Speter case TBOOL: 1033766Speter case TCHAR: 1034766Speter case TINT: 1035766Speter case TSCAL: 103610373Speter postcheck(ap, filetype); 103710373Speter sconv(p2type(filetype), p2type(ap)); 1038766Speter /* and fall through */ 1039766Speter case TDOUBLE: 1040766Speter case TPTR: 104118467Sralph putop( PCC_ASSIGN , p2type( ap ) ); 1042766Speter putdot( filename , line ); 1043766Speter break; 1044766Speter default: 104518467Sralph putstrop(PCC_STASG, 104618467Sralph PCCM_ADDTYPE(p2type(ap), PCCTM_PTR), 104715934Smckusick (int) lwidth(ap), 104811856Speter align(ap)); 1049766Speter putdot( filename , line ); 1050766Speter break; 1051766Speter } 1052766Speter /* 1053766Speter * get(file); 1054766Speter */ 105518467Sralph putleaf( PCC_ICON , 0 , 0 105618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1057766Speter , "_GET" ); 105815934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 105918467Sralph PCCTM_PTR|PCCT_STRTY ); 106018467Sralph putop( PCC_CALL , PCCT_INT ); 1061766Speter putdot( filename , line ); 1062766Speter continue; 1063766Speter } 1064766Speter /* 1065766Speter * if you get to here, you are reading from 1066766Speter * a text file. only possiblities are: 1067766Speter * character, integer, real, or scalar. 1068766Speter * read( f , foo , ... ) is done as 1069766Speter * foo := read( f ) with rangechecking 1070766Speter * if appropriate. 1071766Speter */ 1072766Speter typ = classify(ap); 1073766Speter op = rdops(typ); 1074766Speter if (op == NIL) { 1075766Speter error("Can't read %ss from a text file", clnames[typ]); 1076766Speter continue; 1077766Speter } 1078766Speter /* 1079766Speter * left hand side of foo := read( f ) 1080766Speter */ 1081766Speter ap = lvalue( al , MOD|ASGN|NOUSE , RREQ ); 1082766Speter if ( isa( ap , "bsci" ) ) { 1083766Speter precheck( ap , "_RANG4" , "_RSNG4" ); 1084766Speter } 1085766Speter switch ( op ) { 1086766Speter case O_READC: 1087766Speter readname = "_READC"; 108818467Sralph readtype = PCCT_INT; 1089766Speter break; 1090766Speter case O_READ4: 1091766Speter readname = "_READ4"; 109218467Sralph readtype = PCCT_INT; 1093766Speter break; 1094766Speter case O_READ8: 1095766Speter readname = "_READ8"; 109618467Sralph readtype = PCCT_DOUBLE; 1097766Speter break; 1098766Speter case O_READE: 1099766Speter readname = "_READE"; 110018467Sralph readtype = PCCT_INT; 1101766Speter break; 1102766Speter } 110318467Sralph putleaf( PCC_ICON , 0 , 0 110418467Sralph , (int) PCCM_ADDTYPE( PCCTM_FTN | readtype , PCCTM_PTR ) 1105766Speter , readname ); 110615934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 110718467Sralph PCCTM_PTR|PCCT_STRTY ); 1108766Speter if ( op == O_READE ) { 1109766Speter sprintf( format , PREFIXFORMAT , LABELPREFIX 1110766Speter , listnames( ap ) ); 111118467Sralph putleaf( PCC_ICON , 0, 0, (int) (PCCTM_PTR | PCCT_CHAR), 111215934Smckusick format ); 111318467Sralph putop( PCC_CM , PCCT_INT ); 11141629Speter warning(); 1115766Speter if (opt('s')) { 1116766Speter standard(); 1117766Speter } 11181629Speter error("Reading scalars from text files is non-standard"); 1119766Speter } 112018467Sralph putop( PCC_CALL , (int) readtype ); 1121766Speter if ( isa( ap , "bcsi" ) ) { 112218467Sralph postcheck(ap, readtype==PCCT_INT?nl+T4INT:nl+TDOUBLE); 1123766Speter } 112415934Smckusick sconv((int) readtype, p2type(ap)); 112518467Sralph putop( PCC_ASSIGN , p2type( ap ) ); 1126766Speter putdot( filename , line ); 1127766Speter } 1128766Speter /* 1129766Speter * Done with arguments. 1130766Speter * Handle readln and 1131766Speter * insufficient number of args. 1132766Speter */ 1133766Speter if (p->value[0] == O_READLN) { 1134766Speter if (filetype != nl+T1CHAR) 1135766Speter error("Can't 'readln' a non text file"); 113618467Sralph putleaf( PCC_ICON , 0 , 0 113718467Sralph , (int) PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1138766Speter , "_READLN" ); 113915934Smckusick putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , 114018467Sralph PCCTM_PTR|PCCT_STRTY ); 114118467Sralph putop( PCC_CALL , PCCT_INT ); 1142766Speter putdot( filename , line ); 1143766Speter } else if (argc == 0) 1144766Speter error("read requires an argument"); 1145766Speter return; 1146766Speter 1147766Speter case O_GET: 1148766Speter case O_PUT: 1149766Speter if (argc != 1) { 1150766Speter error("%s expects one argument", p->symbol); 1151766Speter return; 1152766Speter } 115318467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 115418467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1155766Speter , "_UNIT" ); 115615934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 115715934Smckusick if (ap == NLNIL) 1158766Speter return; 1159766Speter if (ap->class != FILET) { 1160766Speter error("Argument to %s must be a file, not %s", p->symbol, nameof(ap)); 1161766Speter return; 1162766Speter } 116318467Sralph putop( PCC_CALL , PCCT_INT ); 116418467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 1165766Speter putdot( filename , line ); 116618467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1167766Speter , op == O_GET ? "_GET" : "_PUT" ); 116818467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 116918467Sralph putop( PCC_CALL , PCCT_INT ); 1170766Speter putdot( filename , line ); 1171766Speter return; 1172766Speter 1173766Speter case O_RESET: 1174766Speter case O_REWRITE: 1175766Speter if (argc == 0 || argc > 2) { 1176766Speter error("%s expects one or two arguments", p->symbol); 1177766Speter return; 1178766Speter } 1179766Speter if (opt('s') && argc == 2) { 1180766Speter standard(); 1181766Speter error("Two argument forms of reset and rewrite are non-standard"); 1182766Speter } 118318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT 1184766Speter , op == O_RESET ? "_RESET" : "_REWRITE" ); 118515934Smckusick ap = stklval(argv->list_node.list, MOD|NOUSE); 118615934Smckusick if (ap == NLNIL) 1187766Speter return; 1188766Speter if (ap->class != FILET) { 1189766Speter error("First argument to %s must be a file, not %s", p->symbol, nameof(ap)); 1190766Speter return; 1191766Speter } 1192766Speter if (argc == 2) { 1193766Speter /* 1194766Speter * Optional second argument 1195766Speter * is a string name of a 1196766Speter * UNIX (R) file to be associated. 1197766Speter */ 119815934Smckusick al = argv->list_node.next; 119915934Smckusick al = (struct tnode *) stkrval(al->list_node.list, 120015934Smckusick NLNIL , (long) RREQ ); 120115934Smckusick if (al == TR_NIL) 1202766Speter return; 120315934Smckusick if (classify((struct nl *) al) != TSTR) { 120415934Smckusick error("Second argument to %s must be a string, not %s", p->symbol, nameof((struct nl *) al)); 1205766Speter return; 1206766Speter } 120715934Smckusick strnglen = width((struct nl *) al); 1208766Speter } else { 120918467Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 1210766Speter strnglen = 0; 1211766Speter } 121218467Sralph putop( PCC_CM , PCCT_INT ); 121318467Sralph putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 ); 121418467Sralph putop( PCC_CM , PCCT_INT ); 121518467Sralph putleaf( PCC_ICON , text(ap) ? 0: width(ap->type) , 0 , PCCT_INT , (char *) 0 ); 121618467Sralph putop( PCC_CM , PCCT_INT ); 121718467Sralph putop( PCC_CALL , PCCT_INT ); 1218766Speter putdot( filename , line ); 1219766Speter return; 1220766Speter 1221766Speter case O_NEW: 1222766Speter case O_DISPOSE: 1223766Speter if (argc == 0) { 1224766Speter error("%s expects at least one argument", p->symbol); 1225766Speter return; 1226766Speter } 122715934Smckusick alv = argv->list_node.list; 12287967Smckusick codeoff(); 12299139Smckusick ap = stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD ); 12307967Smckusick codeon(); 123115934Smckusick if (ap == NLNIL) 1232766Speter return; 1233766Speter if (ap->class != PTR) { 1234766Speter error("(First) argument to %s must be a pointer, not %s", p->symbol, nameof(ap)); 1235766Speter return; 1236766Speter } 1237766Speter ap = ap->type; 123815934Smckusick if (ap == NLNIL) 1239766Speter return; 12409139Smckusick if (op == O_NEW) 12419139Smckusick cmd = "_NEW"; 12429139Smckusick else /* op == O_DISPOSE */ 12437967Smckusick if ((ap->nl_flags & NFILES) != 0) 12447967Smckusick cmd = "_DFDISPOSE"; 12457967Smckusick else 12467967Smckusick cmd = "_DISPOSE"; 124718467Sralph putleaf( PCC_ICON, 0, 0, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ), cmd); 124815934Smckusick (void) stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD ); 124915934Smckusick argv = argv->list_node.next; 125015934Smckusick if (argv != TR_NIL) { 1251766Speter if (ap->class != RECORD) { 1252766Speter error("Record required when specifying variant tags"); 1253766Speter return; 1254766Speter } 125515934Smckusick for (; argv != TR_NIL; argv = argv->list_node.next) { 1256766Speter if (ap->ptr[NL_VARNT] == NIL) { 1257766Speter error("Too many tag fields"); 1258766Speter return; 1259766Speter } 126015934Smckusick if (!isconst(argv->list_node.list)) { 1261766Speter error("Second and successive arguments to %s must be constants", p->symbol); 1262766Speter return; 1263766Speter } 126415934Smckusick gconst(argv->list_node.list); 1265766Speter if (con.ctype == NIL) 1266766Speter return; 126715934Smckusick if (incompat(con.ctype, (ap->ptr[NL_TAG])->type , TR_NIL )) { 1268766Speter cerror("Specified tag constant type clashed with variant case selector type"); 1269766Speter return; 1270766Speter } 1271766Speter for (ap = ap->ptr[NL_VARNT]; ap != NIL; ap = ap->chain) 1272766Speter if (ap->range[0] == con.crval) 1273766Speter break; 1274766Speter if (ap == NIL) { 1275766Speter error("No variant case label value equals specified constant value"); 1276766Speter return; 1277766Speter } 1278766Speter ap = ap->ptr[NL_VTOREC]; 1279766Speter } 1280766Speter } 128118467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 128218467Sralph putop( PCC_CM , PCCT_INT ); 128318467Sralph putop( PCC_CALL , PCCT_INT ); 1284766Speter putdot( filename , line ); 12859139Smckusick if (opt('t') && op == O_NEW) { 128618467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 12879139Smckusick , "_blkclr" ); 128815934Smckusick (void) stkrval(alv, NLNIL , (long) RREQ ); 128918467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 129018467Sralph putop( PCC_CM , PCCT_INT ); 129118467Sralph putop( PCC_CALL , PCCT_INT ); 12929139Smckusick putdot( filename , line ); 12939139Smckusick } 1294766Speter return; 1295766Speter 1296766Speter case O_DATE: 1297766Speter case O_TIME: 1298766Speter if (argc != 1) { 1299766Speter error("%s expects one argument", p->symbol); 1300766Speter return; 1301766Speter } 130218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1303766Speter , op == O_DATE ? "_DATE" : "_TIME" ); 130415934Smckusick ap = stklval(argv->list_node.list, MOD|NOUSE); 1305766Speter if (ap == NIL) 1306766Speter return; 1307766Speter if (classify(ap) != TSTR || width(ap) != 10) { 1308766Speter error("Argument to %s must be a alfa, not %s", p->symbol, nameof(ap)); 1309766Speter return; 1310766Speter } 131118467Sralph putop( PCC_CALL , PCCT_INT ); 1312766Speter putdot( filename , line ); 1313766Speter return; 1314766Speter 1315766Speter case O_HALT: 1316766Speter if (argc != 0) { 1317766Speter error("halt takes no arguments"); 1318766Speter return; 1319766Speter } 132018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1321766Speter , "_HALT" ); 1322766Speter 132318467Sralph putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); 1324766Speter putdot( filename , line ); 132515934Smckusick noreach = TRUE; 1326766Speter return; 1327766Speter 1328766Speter case O_ARGV: 1329766Speter if (argc != 2) { 1330766Speter error("argv takes two arguments"); 1331766Speter return; 1332766Speter } 133318467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1334766Speter , "_ARGV" ); 133515934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 133615934Smckusick if (ap == NLNIL) 1337766Speter return; 1338766Speter if (isnta(ap, "i")) { 1339766Speter error("argv's first argument must be an integer, not %s", nameof(ap)); 1340766Speter return; 1341766Speter } 134215934Smckusick al = argv->list_node.next; 134315934Smckusick ap = stklval(al->list_node.list, MOD|NOUSE); 134415934Smckusick if (ap == NLNIL) 1345766Speter return; 1346766Speter if (classify(ap) != TSTR) { 1347766Speter error("argv's second argument must be a string, not %s", nameof(ap)); 1348766Speter return; 1349766Speter } 135018467Sralph putop( PCC_CM , PCCT_INT ); 135118467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 135218467Sralph putop( PCC_CM , PCCT_INT ); 135318467Sralph putop( PCC_CALL , PCCT_INT ); 1354766Speter putdot( filename , line ); 1355766Speter return; 1356766Speter 1357766Speter case O_STLIM: 1358766Speter if (argc != 1) { 1359766Speter error("stlimit requires one argument"); 1360766Speter return; 1361766Speter } 136218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1363766Speter , "_STLIM" ); 136415934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 136515934Smckusick if (ap == NLNIL) 1366766Speter return; 1367766Speter if (isnta(ap, "i")) { 1368766Speter error("stlimit's argument must be an integer, not %s", nameof(ap)); 1369766Speter return; 1370766Speter } 137118467Sralph putop( PCC_CALL , PCCT_INT ); 1372766Speter putdot( filename , line ); 1373766Speter return; 1374766Speter 1375766Speter case O_REMOVE: 1376766Speter if (argc != 1) { 1377766Speter error("remove expects one argument"); 1378766Speter return; 1379766Speter } 138018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1381766Speter , "_REMOVE" ); 138215934Smckusick ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ ); 138315934Smckusick if (ap == NLNIL) 1384766Speter return; 1385766Speter if (classify(ap) != TSTR) { 1386766Speter error("remove's argument must be a string, not %s", nameof(ap)); 1387766Speter return; 1388766Speter } 138918467Sralph putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 ); 139018467Sralph putop( PCC_CM , PCCT_INT ); 139118467Sralph putop( PCC_CALL , PCCT_INT ); 1392766Speter putdot( filename , line ); 1393766Speter return; 1394766Speter 1395766Speter case O_LLIMIT: 1396766Speter if (argc != 2) { 1397766Speter error("linelimit expects two arguments"); 1398766Speter return; 1399766Speter } 140018467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1401766Speter , "_LLIMIT" ); 140215934Smckusick ap = stklval(argv->list_node.list, NOFLAGS|NOUSE); 140315934Smckusick if (ap == NLNIL) 1404766Speter return; 1405766Speter if (!text(ap)) { 1406766Speter error("linelimit's first argument must be a text file, not %s", nameof(ap)); 1407766Speter return; 1408766Speter } 140915934Smckusick al = argv->list_node.next; 141015934Smckusick ap = stkrval(al->list_node.list, NLNIL , (long) RREQ ); 141115934Smckusick if (ap == NLNIL) 1412766Speter return; 1413766Speter if (isnta(ap, "i")) { 1414766Speter error("linelimit's second argument must be an integer, not %s", nameof(ap)); 1415766Speter return; 1416766Speter } 141718467Sralph putop( PCC_CM , PCCT_INT ); 141818467Sralph putop( PCC_CALL , PCCT_INT ); 1419766Speter putdot( filename , line ); 1420766Speter return; 1421766Speter case O_PAGE: 1422766Speter if (argc != 1) { 1423766Speter error("page expects one argument"); 1424766Speter return; 1425766Speter } 142618467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 142718467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1428766Speter , "_UNIT" ); 142915934Smckusick ap = stklval(argv->list_node.list, NOFLAGS); 143015934Smckusick if (ap == NLNIL) 1431766Speter return; 1432766Speter if (!text(ap)) { 1433766Speter error("Argument to page must be a text file, not %s", nameof(ap)); 1434766Speter return; 1435766Speter } 143618467Sralph putop( PCC_CALL , PCCT_INT ); 143718467Sralph putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); 1438766Speter putdot( filename , line ); 1439766Speter if ( opt( 't' ) ) { 144018467Sralph putleaf( PCC_ICON , 0 , 0 144118467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1442766Speter , "_PAGE" ); 144318467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 1444766Speter } else { 144518467Sralph putleaf( PCC_ICON , 0 , 0 144618467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1447766Speter , "_fputc" ); 144818467Sralph putleaf( PCC_ICON , '\f' , 0 , (int) PCCT_CHAR , (char *) 0 ); 144918467Sralph putleaf( PCC_ICON , 0 , 0 145018467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1451766Speter , "_ACTFILE" ); 145218467Sralph putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 145318467Sralph putop( PCC_CALL , PCCT_INT ); 145418467Sralph putop( PCC_CM , PCCT_INT ); 1455766Speter } 145618467Sralph putop( PCC_CALL , PCCT_INT ); 1457766Speter putdot( filename , line ); 1458766Speter return; 1459766Speter 14607928Smckusick case O_ASRT: 14617928Smckusick if (!opt('t')) 14627928Smckusick return; 14637928Smckusick if (argc == 0 || argc > 2) { 14647928Smckusick error("Assert expects one or two arguments"); 14657928Smckusick return; 14667928Smckusick } 14679139Smckusick if (argc == 2) 14689139Smckusick cmd = "_ASRTS"; 14699139Smckusick else 14709139Smckusick cmd = "_ASRT"; 147118467Sralph putleaf( PCC_ICON , 0 , 0 147218467Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , cmd ); 147315934Smckusick ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ ); 147415934Smckusick if (ap == NLNIL) 14757928Smckusick return; 14767928Smckusick if (isnta(ap, "b")) 14777928Smckusick error("Assert expression must be Boolean, not %ss", nameof(ap)); 14787928Smckusick if (argc == 2) { 14797928Smckusick /* 14807928Smckusick * Optional second argument is a string specifying 14817928Smckusick * why the assertion failed. 14827928Smckusick */ 148315934Smckusick al = argv->list_node.next; 148415934Smckusick al = (struct tnode *) stkrval(al->list_node.list, NLNIL , (long) RREQ ); 148515934Smckusick if (al == TR_NIL) 14867928Smckusick return; 148715934Smckusick if (classify((struct nl *) al) != TSTR) { 148815934Smckusick error("Second argument to assert must be a string, not %s", nameof((struct nl *) al)); 14897928Smckusick return; 14907928Smckusick } 149118467Sralph putop( PCC_CM , PCCT_INT ); 14927928Smckusick } 149318467Sralph putop( PCC_CALL , PCCT_INT ); 14947928Smckusick putdot( filename , line ); 14957928Smckusick return; 14967928Smckusick 1497766Speter case O_PACK: 1498766Speter if (argc != 3) { 1499766Speter error("pack expects three arguments"); 1500766Speter return; 1501766Speter } 150218467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1503766Speter , "_PACK" ); 1504766Speter pu = "pack(a,i,z)"; 150515934Smckusick pua = (al = argv)->list_node.list; 150615934Smckusick pui = (al = al->list_node.next)->list_node.list; 150715934Smckusick puz = (al = al->list_node.next)->list_node.list; 1508766Speter goto packunp; 1509766Speter case O_UNPACK: 1510766Speter if (argc != 3) { 1511766Speter error("unpack expects three arguments"); 1512766Speter return; 1513766Speter } 151418467Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 1515766Speter , "_UNPACK" ); 1516766Speter pu = "unpack(z,a,i)"; 151715934Smckusick puz = (al = argv)->list_node.list; 151815934Smckusick pua = (al = al->list_node.next)->list_node.list; 151915934Smckusick pui = (al = al->list_node.next)->list_node.list; 1520766Speter packunp: 152115934Smckusick ap = stkrval(pui, NLNIL , (long) RREQ ); 1522766Speter if (ap == NIL) 1523766Speter return; 1524766Speter ap = stklval(pua, op == O_PACK ? NOFLAGS : MOD|NOUSE); 1525766Speter if (ap == NIL) 1526766Speter return; 1527766Speter if (ap->class != ARRAY) { 1528766Speter error("%s requires a to be an unpacked array, not %s", pu, nameof(ap)); 1529766Speter return; 1530766Speter } 153118467Sralph putop( PCC_CM , PCCT_INT ); 153215934Smckusick al = (struct tnode *) stklval(puz, op == O_UNPACK ? NOFLAGS : MOD|NOUSE); 153315934Smckusick if (((struct nl *) al)->class != ARRAY) { 1534766Speter error("%s requires z to be a packed array, not %s", pu, nameof(ap)); 1535766Speter return; 1536766Speter } 153715934Smckusick if (((struct nl *) al)->type == NIL || 153815934Smckusick ((struct nl *) ap)->type == NIL) 1539766Speter return; 154015934Smckusick if (((struct nl *) al)->type != ((struct nl *) ap)->type) { 1541766Speter error("%s requires a and z to be arrays of the same type", pu, nameof(ap)); 1542766Speter return; 1543766Speter } 154418467Sralph putop( PCC_CM , PCCT_INT ); 154515934Smckusick k = width((struct nl *) al); 1546766Speter itemwidth = width(ap->type); 1547766Speter ap = ap->chain; 154815934Smckusick al = ((struct tnode *) ((struct nl *) al)->chain); 154915934Smckusick if (ap->chain != NIL || ((struct nl *) al)->chain != NIL) { 1550766Speter error("%s requires a and z to be single dimension arrays", pu); 1551766Speter return; 1552766Speter } 1553766Speter if (ap == NIL || al == NIL) 1554766Speter return; 1555766Speter /* 1556766Speter * al is the range for z i.e. u..v 1557766Speter * ap is the range for a i.e. m..n 1558766Speter * i will be n-m+1 1559766Speter * j will be v-u+1 1560766Speter */ 1561766Speter i = ap->range[1] - ap->range[0] + 1; 156215934Smckusick j = ((struct nl *) al)->range[1] - 156315934Smckusick ((struct nl *) al)->range[0] + 1; 1564766Speter if (i < j) { 156515934Smckusick error("%s cannot have more elements in a (%d) than in z (%d)", pu, (char *) j, (char *) i); 1566766Speter return; 1567766Speter } 1568766Speter /* 1569766Speter * get n-m-(v-u) and m for the interpreter 1570766Speter */ 1571766Speter i -= j; 1572766Speter j = ap->range[0]; 157318467Sralph putleaf( PCC_ICON , itemwidth , 0 , PCCT_INT , (char *) 0 ); 157418467Sralph putop( PCC_CM , PCCT_INT ); 157518467Sralph putleaf( PCC_ICON , j , 0 , PCCT_INT , (char *) 0 ); 157618467Sralph putop( PCC_CM , PCCT_INT ); 157718467Sralph putleaf( PCC_ICON , i , 0 , PCCT_INT , (char *) 0 ); 157818467Sralph putop( PCC_CM , PCCT_INT ); 157918467Sralph putleaf( PCC_ICON , k , 0 , PCCT_INT , (char *) 0 ); 158018467Sralph putop( PCC_CM , PCCT_INT ); 158118467Sralph putop( PCC_CALL , PCCT_INT ); 1582766Speter putdot( filename , line ); 1583766Speter return; 1584766Speter case 0: 15857928Smckusick error("%s is an unimplemented extension", p->symbol); 1586766Speter return; 1587766Speter 1588766Speter default: 1589766Speter panic("proc case"); 1590766Speter } 1591766Speter } 1592766Speter #endif PC 1593