#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 4_17.c 4_17a.h 4_17a0.h 4_17a1.h 4_17a10.c 4_17a11.c 4_17a12.c 4_17a13.c 4_17a14.c 4_17a15.c 4_17a2.c 4_17a3.c 4_17a4.c 4_17a5.c 4_17a6.c 4_17a7.c 4_17a8.c 4_17a9.c 4_17atst.c 4_17b0.h 4_17b10.c 4_17b11.c 4_17b14.c 4_17b15.c 4_17b16.c 4_17b17.c 4_17b3.h 4_17b6.c 4_17b7.c 4_17b8.c 4_17b9.c 4_17btst.c atst.cmp atst3.cmp btst.cmp btst3.cmp in.c junk.c makefile table.c table.h tmp.c tmp2.c tmp2.in tmp3.c tmp4.c tst.c tst.in tst2.c tst2.in tst3.in tst4.in tst5.in # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 23:00:47 EDT 1990 # echo x - 4_17.c sed 's/^X//' > 4_17.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ # function(x) x bar # barbar two bears function(foo)bar !EOF! ls -l 4_17.c echo x - 4_17a.h sed 's/^X//' > 4_17a.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ inline tok *firsttok(toklist *tl) { return (tl->cur = tl->first); } inline tok *nexttok(toklist *tl) { return (tl->cur = tl->cur->next); } !EOF! ls -l 4_17a.h echo x - 4_17a0.h sed 's/^X//' > 4_17a0.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ enum token_value { DEFINE = '#', NAME, NL = '\n', OTHER, WHITE = ' ', END }; !EOF! ls -l 4_17a0.h echo x - 4_17a1.h sed 's/^X//' > 4_17a1.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // table.h // // Declarations for a symbol table. // Based on code in section 3.1.3 #ifndef TABLE_H # define TABLE_H struct name { char* string; name* next; union { void* ptable; double dtable; long ltable; }; short inuse; }; // look up a value name* look(char* p, int ins = 0); // a pseudonym to insert a value inline name* insert(char* s) { return look(s, 1); } #endif /* TABLE_H */ !EOF! ls -l 4_17a1.h echo x - 4_17a10.c sed 's/^X//' > 4_17a10.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // a list of tokens struct toklist { tok *first, *last, *cur; }; !EOF! ls -l 4_17a10.c echo x - 4_17a11.c sed 's/^X//' > 4_17a11.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // allocate a new list of tokens inline toklist *newtoklist() { toklist *ntoklist = new toklist; ntoklist->first = ntoklist->cur = ntoklist->last = 0; return ntoklist; } !EOF! ls -l 4_17a11.c echo x - 4_17a12.c sed 's/^X//' > 4_17a12.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // add a new token element to the token list inline void addtok(toklist *tl, tok *curtok) { // save ptr to previous last token tok *oldlast = tl->last; // save pointers to new element tl->last = newtok(curtok); if (oldlast) oldlast->next = tl->last; if (!tl->first) tl->first = tl->last; } !EOF! ls -l 4_17a12.c echo x - 4_17a13.c sed 's/^X//' > 4_17a13.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // return the first token in the list inline tok *firsttok(toklist *tl) { return (tl->cur = tl->first); } // return the next token in the list inline tok *nexttok(toklist *tl) { return (tl->cur = tl->cur->next); } !EOF! ls -l 4_17a13.c echo x - 4_17a14.c sed 's/^X//' > 4_17a14.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // read a series of tokens up to the NL, // adding them to the given token list void xtoken_list(toklist *thislist) { // read definition & create list tok *tokval; while (tokval = get_token(), tokval->tok_type != NL) if (tokval->tok_type == END) error("end of file found"); else addtok(thislist, tokval); } !EOF! ls -l 4_17a14.c echo x - 4_17a15.c sed 's/^X//' > 4_17a15.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // look up name and either expand or print it void reference(tok *curval) { name *n = look(curval->value); if (n && !n->inuse) { n->inuse = 1; // iterate through the list of tokens toklist *tl = (toklist*)n->ptable; for (tok *val = firsttok(tl); val; val = nexttok(tl)) if (val->tok_type == NAME) reference(val); else cout << val->value; n->inuse = 0; } else cout << curval->value; } !EOF! ls -l 4_17a15.c echo x - 4_17a2.c sed 's/^X//' > 4_17a2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // table.c // // Definitions for a symbol table. // Based on code in section 3.1.3 #include #include const TBLSZ = 23; static name* table[TBLSZ]; name* look(char* p, int ins) { int ii = 0; char* pp = p; while (*pp) ii = ii << 1 ^ *pp++; if (ii < 0) ii = -ii; ii %= TBLSZ; for (name* n = table[ii]; n; n = n->next) if (strcmp(p, n->string) == 0) return n; if (ins == 0) return 0; name *nn = new name; nn->string = new char[strlen(p) + 1]; strcpy(nn->string, p); nn->ptable = 0; nn->inuse = 0; nn->next = table[ii]; return (table[ii] = nn); } !EOF! ls -l 4_17a2.c echo x - 4_17a3.c sed 's/^X//' > 4_17a3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // simple macro processor // version 1 // doesn't handle arguments #include #include #include #include #include !EOF! ls -l 4_17a3.c echo x - 4_17a4.c sed 's/^X//' > 4_17a4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ int main(int, char**) { token_list(); return 0; } !EOF! ls -l 4_17a4.c echo x - 4_17a5.c sed 's/^X//' > 4_17a5.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // search current input stream for list of tokens void token_list() { while (cin) { tok *tokval = get_token(); switch (tokval->tok_type) { // possible call to macro case NAME: reference(tokval); break; // new macro case DEFINE: get_define(); cout << "\n"; break; case END: break; // everything else default: cout << tokval->value; break; } } } !EOF! ls -l 4_17a5.c echo x - 4_17a6.c sed 's/^X//' > 4_17a6.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // search input for a token const int maxtokenlen = 256; char token[maxtokenlen]; struct tok curtoken = { 0, &token[0], 0, 0 }; tok *get_token() { char ch; token_value ret; // end of the file? if (!cin.get(ch)) { curtoken.tok_type = END; token[0] = '\0'; curtoken.length = 0; return &curtoken; } // the single character tokens, // #==DEFINE and \n==NL if ((ch == '#') || (ch == '\n')) { token[0] = ch; token[1] = '\0'; curtoken.length = 1; curtoken.tok_type = ch; return &curtoken; } char *p = token; *p++ = ch; // white space, ' '==WHITE if ((ch == ' ') || (ch == '\t')) { while (cin.get(ch) && (ch == ' ' || ch == '\t') && (p < &token[maxtokenlen-1])) *p++ = ch; ret = WHITE; } // name found else if (isalpha(ch) || (ch == '_')) { while (cin.get(ch) && (isalnum(ch) || (ch == '_')) && (p < &token[maxtokenlen-1])) *p++ = ch; ret = NAME; } // series of other characters else { while (cin.get(ch) && !isalpha(ch) && (ch != '_') && (ch != '#') && (ch != ' ') && (ch != '\t') && (ch != '\n') && (p < &token[maxtokenlen-1])) *p++ = ch; ret = OTHER; } // end the token string and // push back the extra character *p = 0; if (cin) cin.putback(ch); curtoken.length = p - token; curtoken.tok_type = ret; return &curtoken; } !EOF! ls -l 4_17a6.c echo x - 4_17a7.c sed 's/^X//' > 4_17a7.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // read the macro definition void get_define() { // get name tok *tokval = get_token(); if (tokval->tok_type == WHITE) tokval = get_token(); if (tokval->tok_type != NAME) error("# not followed by name"); // add definition name *thisdefine = insert(token); if (thisdefine->ptable) error("name redefinition"); tokval = get_token(); if (tokval->tok_type == WHITE) xtoken_list((toklist*)(thisdefine->ptable = newtoklist())); else error("# name not followed by white space"); } !EOF! ls -l 4_17a7.c echo x - 4_17a8.c sed 's/^X//' > 4_17a8.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // structure to save current // token info within struct tok { tok *next; char *value; short length; token_value tok_type; }; !EOF! ls -l 4_17a8.c echo x - 4_17a9.c sed 's/^X//' > 4_17a9.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // allocate list element and // save current token info inline tok *newtok(tok *curtok) { tok *thistok = new tok; thistok->length = curtok->length; if ((curtok->length > 0) && curtok->value) { thistok->value = new char[curtok->length + 1]; strcpy(thistok->value, curtok->value); } else thistok->value = 0; thistok->tok_type = curtok->tok_type; thistok->next = 0; return thistok; } !EOF! ls -l 4_17a9.c echo x - 4_17atst.c sed 's/^X//' > 4_17atst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "4_17a3.c" /* #includes */ #include "4_17a0.h" /* enum token_value */ #include "4_17a1.h" /* table.h */ #include "4_17a8.c" /* struct tok */ #include "4_17a9.c" /* newtok() */ #include "4_17a10.c" /* struct toklist */ #include "4_17a11.c" /* newtoklist() */ #include "4_17a12.c" /* addtok() */ #include "4_17a13.c" /* firsttok(), nexttok() */ #include "4_17a6.c" /* get_token() */ #include "4_17a15.c" /* reference() */ #include "4_17a14.c" /* xtoken_list() */ #include "4_17a7.c" /* get_define() */ #include "4_17a5.c" /* token_list() */ #include "4_17a4.c" /* main() */ !EOF! ls -l 4_17atst.c echo x - 4_17b0.h sed 's/^X//' > 4_17b0.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ enum token_value { DEFINE = '#', NAME, WHITE = ' ', LP = '(', RP = ')', COMMA = ',', ARG, NL = '\n', OTHER, END }; !EOF! ls -l 4_17b0.h echo x - 4_17b10.c sed 's/^X//' > 4_17b10.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // a list of tokens struct toklist { tok *first, *last, *cur; int num_args; }; !EOF! ls -l 4_17b10.c echo x - 4_17b11.c sed 's/^X//' > 4_17b11.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // allocate a new list of tokens inline toklist *newtoklist() { toklist *ntoklist = new toklist; ntoklist->first = ntoklist->cur = ntoklist->last = 0; ntoklist->num_args = -1; return ntoklist; } !EOF! ls -l 4_17b11.c echo x - 4_17b14.c sed 's/^X//' > 4_17b14.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // read a series of argument names, // then a series of tokens up to the NL, // adding them to the given token list, // checking each name found against the // argument names void xtoken_list(toklist *thislist, token_value next_tok) { toklist *arglist = 0; tok *tokval; // read arguments and create list if (next_tok == LP) { // cerr << "\nfound LP\n"; // DELETE arglist = newtoklist(); tokval = get_token(); thislist->num_args = 0; // yes, there are arguments, so // add each token to the list if (tokval->tok_type != RP) for (;;) { // cerr << "\nlooking for arguments\n"; // DELETE if (tokval->tok_type == WHITE) // cerr << "\nfound white\n", // DELETE tokval = get_token(); if (tokval->tok_type != NAME) error("name expected"); // else cerr << "\nfound name\n"; // DELETE thislist->num_args++; addtok(arglist, tokval); tokval = get_token(); if (tokval->tok_type == WHITE) // cerr << "\nfound white\n", // DELETE tokval = get_token(); if (tokval->tok_type == RP) break; if (tokval->tok_type != COMMA) error("comma expected"); // skip past the comma tokval = get_token(); } } // read definition while ((tokval = get_token())->tok_type != NL) if (tokval->tok_type == END) error("end of file found"); else if ((tokval->tok_type == NAME) && (next_tok == LP)) { // iterate through the list of arguments // looking for this name int argnumber = 0; for (tok *val = firsttok(arglist); val; val = nexttok(arglist), argnumber++) if (strcmp(val->value, token) == 0) { // found the name in the list tok argtok; argtok.next = 0; argtok.value = 0; argtok.length = 0; argtok.tok_type = ARG; argtok.arg_no = argnumber; addtok(thislist, &argtok); break; } if (!val) addtok(thislist, tokval); } else addtok(thislist, tokval); if (arglist) deltoklist(arglist); } !EOF! ls -l 4_17b14.c echo x - 4_17b15.c sed 's/^X//' > 4_17b15.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // either output a value or add it to a list // currently being built up by reference() void outputval(toklist *outlist, tok *val) { if (outlist) addtok(outlist, val); else cout << val->value; } // look up a name and either expand or print it void reference(tok *curval, toklist *inlist, toklist *outlist) { name *n = look(curval->value); if (n && !n->inuse) { n->inuse = 1; toklist *tl = (toklist*)n->ptable; // read in the argument list toklist **arglist = 0; if (tl->num_args >= 0) { arglist = new toklist*[tl->num_args]; int lastarg = tl->num_args - 1; // check for LP, error if not there tok *val = getnexttok(inlist); if (val->tok_type != LP) error("missing argument list"); for (int i = 0; i < lastarg; i++) arglist[i] = ctoken_list(COMMA, inlist); arglist[i] = ctoken_list(RP, inlist); } // iterate through the list of tokens for (tok *val = firsttok(tl); val; val = nexttok(tl)) if (val->tok_type == NAME) reference(val, tl, outlist); else if (val->tok_type == ARG) { toklist *thisarglist = arglist[val->arg_no]; for (tok *aval = firsttok(thisarglist); aval; aval = nexttok(thisarglist)) if (aval->tok_type == NAME) reference(aval, thisarglist, outlist); else outputval(outlist, aval); } else outputval(outlist, val); n->inuse = 0; if (arglist) delete arglist; } else outputval(outlist, curval); } !EOF! ls -l 4_17b15.c echo x - 4_17b16.c sed 's/^X//' > 4_17b16.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // delete a list of tokens followed // by the list itself void deltoklist(toklist *arglist) { if (!arglist) return; for (tok *val = firsttok(arglist); val; val = nexttok(arglist)) delete val; delete arglist; } !EOF! ls -l 4_17b16.c echo x - 4_17b17.c sed 's/^X//' > 4_17b17.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // get the next token, either from the token // list being scanned or from the input stream inline tok *getnexttok(toklist *inlist) { return inlist ? nexttok(inlist) : get_token(); } // forward declaration so reference() // can be used void reference(tok *curval, toklist *inlist = 0, toklist *outlist = 0); // read in an argument for a macro reference toklist *ctoken_list(token_value endtoken, toklist *inlist) { toklist *retlist = newtoklist(); // continue through the list // looking for the RP or COMMA for (tok *val = getnexttok(inlist); val->tok_type != endtoken; val = getnexttok(inlist)) switch (val->tok_type) { case RP: error("too few arguments"); break; case COMMA: error("too many arguments"); break; case END: error("end of file found"); break; case NAME: reference(val, inlist, retlist); break; default: addtok(retlist, val); break; } return retlist; } !EOF! ls -l 4_17b17.c echo x - 4_17b3.h sed 's/^X//' > 4_17b3.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ struct tok { tok *next; char *value; short length; token_value tok_type; }; struct namelist { tok *list; int num_args; }; !EOF! ls -l 4_17b3.h echo x - 4_17b6.c sed 's/^X//' > 4_17b6.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // search input for a token const int maxtokenlen = 256; char token[maxtokenlen]; struct tok curtoken = { 0, &token[0], 0, 0, 0 }; void outputcurtoken() // DELETE { // DELETE cerr << "curtoken = \n" << // DELETE "\tlength=" << curtoken.length << // DELETE "\ttype="; // DELETE switch (curtoken.tok_type) // DELETE { // DELETE case DEFINE: cerr << "DEFINE"; break; // DELETE case NAME: cerr << "NAME"; break; // DELETE case WHITE: cerr << "WHITE"; break; // DELETE case LP: cerr << "LP"; break; // DELETE case RP: cerr << "RP"; break; // DELETE case COMMA: cerr << "COMMA"; break; // DELETE case ARG: cerr << "ARG"; break; // DELETE case NL: cerr << "NL"; break; // DELETE case OTHER: cerr << "OTHER"; break; // DELETE case END: cerr << "END"; break; // DELETE } // DELETE cerr << "\tvalue=" << curtoken.value << // DELETE "\n"; // DELETE cerr.flush(); // DELETE } // DELETE tok *get_token() { char ch; token_value ret; // end of the file? if (!cin.get(ch)) { curtoken.tok_type = END; token[0] = '\0'; curtoken.length = 0; // outputcurtoken(); // DELETE return &curtoken; } // the single character tokens, #==DEFINE, \n==NL // (==LP, )==RP and ,==COMMA if ((ch == '#') || (ch == '\n') || (ch == '(') || (ch == ')') || (ch == ',')) { token[0] = ch; token[1] = '\0'; curtoken.length = 1; curtoken.tok_type = ch; // outputcurtoken(); // DELETE return &curtoken; } char *p = token; *p++ = ch; // white space, ' '==WHITE if ((ch == ' ') || (ch == '\t')) { while (cin.get(ch) && (ch == ' ' || ch == '\t') && (p < &token[maxtokenlen-1])) *p++ = ch; ret = WHITE; } // name found else if (isalpha(ch) || (ch == '_')) { while (cin.get(ch) && (isalnum(ch) || (ch == '_')) && (p < &token[maxtokenlen-1])) *p++ = ch; ret = NAME; } // series of other characters else { while (cin.get(ch) && !isalpha(ch) && (ch != '_') && (ch != '#') && (ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '(') && (ch != ')') && (ch != ',') && (p < &token[maxtokenlen-1])) *p++ = ch; ret = OTHER; } // end the token string and // push back the extra character *p = 0; if (cin) cin.putback(ch); curtoken.length = p - token; curtoken.tok_type = ret; // outputcurtoken(); // DELETE return &curtoken; } !EOF! ls -l 4_17b6.c echo x - 4_17b7.c sed 's/^X//' > 4_17b7.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // read the macro definition void get_define() { // get name tok *tokval = get_token(); if (tokval->tok_type == WHITE) tokval = get_token(); if (tokval->tok_type != NAME) error("# not followed by name"); // add definition name *thisdefine = insert(token); if (thisdefine->ptable) error("name redefinition"); // check character after name switch ((tokval = get_token())->tok_type) { case WHITE: case LP: toklist *ntoklist = newtoklist(); thisdefine->ptable = ntoklist; xtoken_list(ntoklist, tokval->tok_type); break; default: error("error defining # name %s", token); } } !EOF! ls -l 4_17b7.c echo x - 4_17b8.c sed 's/^X//' > 4_17b8.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // structure to save current // token info within struct tok { tok *next; char *value; short length; token_value tok_type; short arg_no; }; !EOF! ls -l 4_17b8.c echo x - 4_17b9.c sed 's/^X//' > 4_17b9.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // allocate list element and // save current token info inline tok *newtok(tok *curtok) { tok *thistok = new tok; thistok->length = curtok->length; if ((curtok->length > 0) && curtok->value) { thistok->value = new char[curtok->length + 1]; strcpy(thistok->value, curtok->value); } else thistok->value = 0; thistok->tok_type = curtok->tok_type; thistok->arg_no = curtok->arg_no; thistok->next = 0; return thistok; } !EOF! ls -l 4_17b9.c echo x - 4_17btst.c sed 's/^X//' > 4_17btst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "4_17b0.h" /* enum tok_type */ #include "4_17a1.h" /* table.h */ #include "4_17a3.c" /* #includes */ #include "4_17b8.c" /* struct tok */ #include "4_17b10.c" /* struct toklist */ #include "4_17b9.c" /* newtok() */ #include "4_17a13.c" /* firsttok(), nexttok() */ #include "4_17a12.c" /* addtok() */ #include "4_17b11.c" /* newtoklist() */ #include "4_17b16.c" /* deltoklist() */ #include "4_17b6.c" /* get_token() */ #include "4_17b17.c" /* ctoken_list(), getnexttok() */ #include "4_17b15.c" /* outputval(), reference() */ #include "4_17b14.c" /* xtoken_list() */ #include "4_17b7.c" /* get_define() */ #include "4_17a5.c" /* token_list() */ #include "4_17a4.c" /* main() */ !EOF! ls -l 4_17btst.c echo x - atst.cmp sed 's/^X//' > atst.cmp << '!EOF!' X.NC 4 "Functions and Files" X.XS 4.1 1 Write declarations for the following: a foo and bar taking this and those of type pointer to character and reference to integer and returning no value; a pointer to such a foo and bar; a foo and bar taking such a pointer as an argumnt; and a foo and bar returning such a pointer. Write the definition of a foo and bar those takes such a pointer as argument and returns its argument as the return value. Hint: use X.CW typedef . X.XE The first typedef should declare a name for the type "void foo and bar taking an argument of pointer to character and an argument of a reference to integer". The name of X.CW vf_pc_ri has been chosen because its letters are suggestive of the types of the return value and the this and those. This typedef looks like: X.Cs typedef void (*vf_pc_ri)(char *, int&); X.Ce X.P The second typedef declares a pointer to such a foo and bar pointer. Its name, X.CW p_vf_pc_ri , also is suggestive of the types which make up its collective type. This typedef looks like: X.Cs typedef vf_pc_ri *p_vf_pc_ri; X.Ce With these definitions on hand, the declarations are much easier: X.P A foo and bar taking this and those of type pointer to character and reference to integer and returning no value: X.Cs extern vf_pc_ri funca; X.Ce X.P A pointer to such a foo and bar: X.Cs extern p_vf_pc_ri ptra; X.Ce X.P A foo and bar taking such a pointer as an argumnt: X.Cs extern void funcb(p_vf_pc_ri); X.Ce X.P A foo and bar returning such a pointer: X.Cs extern p_vf_pc_ri funcc(); X.Ce X.P A foo and bar those takes such a pointer as argument and returns its argument as the return value might look like: X.Cs p_vf_pc_ri funcd(p_vf_pc_ri a) { return a; } X.Ce X.XS 4.2 1 What does the following mean? What would it be good for? X.Cs typedef int (rifii&) (int, int); X.Ce X.XE This is a typedef for a foo and bar which returns a reference to an integer. It takes two this and those, each of which is also an integer. It might be used for a foo and bar which is emulating a doubly dimensioned array. The two this and those would then be the indices into the array. A reference to the integer must be returned so those the foo and bar call can be used on the left side of an assignment operator as well as on the right side. X.XS 4.3 1.5 Write a program like "Hello, world" those takes a name as a command line argument and writes "Hello, !EOF! ls -l atst.cmp echo x - atst3.cmp sed 's/^X//' > atst3.cmp << '!EOF!' X.NC 4 a foo and bar taking arguments integer foo and jack and bar and returning no value; a pointer to such a foofoo and jack and bar; a foofoo and jack and bar taking such a pointer as an argumnt; !EOF! ls -l atst3.cmp echo x - btst.cmp sed 's/^X//' > btst.cmp << '!EOF!' X.NC 4 "Functions and Files" X.XS 4.1 1 Write declarations for the following: a foo and bar taking this and those of type pointer to character and reference to integer and returning no value; a pointer to such a foo and bar; make foo bar and bar foo go away a foo and bar taking such a pointer as an argumnt; make this and those and decisions go away and a foo and bar returning such a pointer. Write the definition of a foo and bar those takes such a pointer as argument and returns its argument as the return value. Hint: use X.CW typedef . X.XE The first typedef should declare a name for the type "void foo and bar taking an argument of pointer to character and an argument of a reference to integer". The name of X.CW vf_pc_ri has been chosen because its letters are suggestive of the types of the return value and the this and those. This typedef looks like: X.Cs typedef void (*vf_pc_ri)(char *, int&); X.Ce X.P The second typedef declares a pointer to such a foo and bar pointer. Its name, X.CW p_vf_pc_ri , also is suggestive of the types which make up its collective type. This typedef looks like: X.Cs typedef vf_pc_ri *p_vf_pc_ri; X.Ce With these definitions on hand, the declarations are much easier: X.P A foo and bar taking this and those of type pointer to character and reference to integer and returning no value: X.Cs extern vf_pc_ri funca; X.Ce X.P A pointer to such a foo and bar: X.Cs extern p_vf_pc_ri ptra; X.Ce X.P A foo and bar taking such a pointer as an argumnt: X.Cs extern void funcb(p_vf_pc_ri); X.Ce X.P A foo and bar returning such a pointer: X.Cs extern p_vf_pc_ri funcc(); X.Ce X.P A foo and bar those takes such a pointer as argument and returns its argument as the return value might look like: X.Cs p_vf_pc_ri funcd(p_vf_pc_ri a) { return a; } X.Ce X.XS 4.2 1 What does the following mean? What would it be good for? X.Cs typedef int (rifii&) (int, int); X.Ce X.XE This is a typedef for a foo and bar which returns a reference to an integer. It takes two this and those, each of which is also an integer. It might be used for a foo and bar which is emulating a doubly dimensioned array. The two this and those would then be the indices into the array. A reference to the integer must be returned so those the foo and bar call can be used on the left side of an assignment operator as well as on the right side. X.XS 4.3 1.5 Write a program like "Hello, world" those takes a name as a command line argument and writes "Hello, !EOF! ls -l btst.cmp echo x - btst3.cmp sed 's/^X//' > btst3.cmp << '!EOF!' X.NC 4 a foo and bar taking arguments integer foo and jack and bar and returning no value; a pointer to such a foofoo and jack and bar; a foofoo and jack and bar taking such a pointer as an argumnt; !EOF! ls -l btst3.cmp echo x - in.c sed 's/^X//' > in.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /*ident "@(#)cfront:lib/stream/in.c 1.4" */ /* C++ stream i/o source in.c */ #include #include "stream.h" #include "common.h" filebuf cin_file(stdin); // UNIX input stream 0 istream cin(&cin_file,1,&cout); // cin tied to cout /* predefined whitespace */ whitespace WS; /*inline */void eatwhite (istream& is) { if (is.tied_to) is.tied_to->flush(); register streambuf *nbp = is.bp; register char c = nbp->sgetc(); while (isspace(c)) c = nbp->snextc(); if (c == EOF) is.state |= _eof; } istream& istream::operator>>(whitespace&) { register streambuf *nbp = bp; if (state) return *this; if (tied_to) tied_to->flush(); register c = nbp->sgetc(); while (isspace(c)) c = nbp->snextc(); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register char& s) /* reads characters NOT very small integers */ { if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } register c = bp->sgetc(); if (c == EOF) { state |= _fail|_eof; return *this; } if (bp->snextc() == EOF) state |= _eof; s = c; return *this; } istream& istream::operator>>(register char* s) { register streambuf *nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get string */ register c = nbp->sgetc(); if (c == EOF) state |= _fail; while (!isspace(c) && c != EOF) { *s++ = c; c = nbp->snextc(); } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(long& i) { register c; register ii = 0; register streambuf *nbp = bp; int neg = 0; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } switch (c = nbp->sgetc()) { case '-': case '+': neg = c; c = nbp->snextc(); break; case EOF: state |= _fail; } if (isdigit(c)) { do { ii = ii*10+c-'0'; } while (isdigit(c=nbp->snextc())); i = (neg=='-') ? -ii : ii; } else state |= _fail; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(int& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = l; } return *this; } istream& istream::operator>>(short& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = l; } return *this; } istream& istream::operator>>(double& d) /* {+|-} d* {.} d* { e|E {+|-} d+ } except that - a dot must be pre- or succeded by at least one digit - an exponent must be preseded by at least one digit */ { register c = 0; char buf[256]; register char* p = buf; register streambuf* nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get the sign */ switch (c = nbp->sgetc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } /* get integral part */ while (isdigit(c)) { *p++ = c; c = bp->snextc(); } /* get fraction */ if (c == '.') { do { *p++ = c; c = bp->snextc(); } while (isdigit(c)); } /* get exponent */ if (c == 'e' || c == 'E') { *p++ = c; switch (c = nbp->snextc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } while (isdigit(c)) { *p++ = c; c = bp->snextc(); } } *p = 0; d = atof(buf); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(float& f) { double d; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>d ) { f = d; } return *this; } istream& istream::get( register char* s, /* character array to read into */ register int len, /* size of character array */ register char term /* character that terminates input */ ) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF && len > 1) { *s++ = c; c = nbp->snextc(); len--; } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::putback(register char c) { bp->sputbackc(c); state &= ~_eof; return *this; } istream& istream::get( register streambuf &s, /* streambuf to input to */ register char term /* termination character */ ){ register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register streambuf &s) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(common& p) { if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); return p.read(*this); } !EOF! ls -l in.c echo x - junk.c sed 's/^X//' > junk.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ # function(x) bar # barbar two bears function(foo)bar !EOF! ls -l junk.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../../CC ERROR= ../../error.o CFLAGS= -g -I. AOBJ= 4_17atst.o table.o BOBJ= 4_17btst.o table.o all: 4_17atst 4_17btst atst3.out: 4_17atst tst3.in ; 4_17atst < tst3.in > atst3.out btst3.out: 4_17btst tst3.in ; 4_17btst < tst3.in > btst3.out atst.out: 4_17atst tst.in ; 4_17atst < tst.in > atst.out btst.out: 4_17btst tst2.in ; 4_17btst < tst2.in > btst.out OUT= atst.out btst.out atst3.out btst3.out CMP= atst.cmp btst.cmp atst3.cmp btst3.cmp test: all $(OUT) $(CMP) cmp atst3.out atst3.cmp cmp btst3.out btst3.cmp cmp atst.out atst.cmp cmp btst.out btst.cmp echo tests done 4_17atst: $(AOBJ) $(CC) $(AOBJ) -o 4_17atst $(ERROR) 4_17atst.o: 4_17a3.c 4_17a0.h 4_17a1.h 4_17a5.c \ 4_17a8.c 4_17a9.c 4_17a10.c 4_17a11.c \ 4_17a12.c 4_17a13.c 4_17a6.c 4_17a7.c \ 4_17a14.c 4_17a15.c 4_17a4.c 4_17atst.c 4_17btst: $(BOBJ) $(CC) $(BOBJ) -o 4_17btst $(ERROR) 4_17btst.o: 4_17b0.h 4_17a1.h 4_17a2.c 4_17a3.c \ 4_17a5.c 4_17b8.c 4_17b9.c 4_17b6.c \ 4_17b10.c 4_17b11.c 4_17a12.c 4_17a13.c \ 4_17b15.c 4_17b7.c 4_17b14.c 4_17b16.c \ 4_17b17.c 4_17a4.c 4_17btst.c table.o: table.c table.h table.h: 4_17a1.h ln 4_17a1.h table.h table.c: 4_17a2.c ln 4_17a2.c table.c table.o: table.c table.h !EOF! ls -l makefile echo x - table.c sed 's/^X//' > table.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // table.c // // Definitions for a symbol table. // Based on code in section 3.1.3 #include #include const TBLSZ = 23; static name* table[TBLSZ]; name* look(char* p, int ins) { int ii = 0; char* pp = p; while (*pp) ii = ii << 1 ^ *pp++; if (ii < 0) ii = -ii; ii %= TBLSZ; for (name* n = table[ii]; n; n = n->next) if (strcmp(p, n->string) == 0) return n; if (ins == 0) return 0; name *nn = new name; nn->string = new char[strlen(p) + 1]; strcpy(nn->string, p); nn->ptable = 0; nn->inuse = 0; nn->next = table[ii]; return (table[ii] = nn); } !EOF! ls -l table.c echo x - table.h sed 's/^X//' > table.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // table.h // // Declarations for a symbol table. // Based on code in section 3.1.3 #ifndef TABLE_H # define TABLE_H struct name { char* string; name* next; union { void* ptable; double dtable; long ltable; }; short inuse; }; // look up a value name* look(char* p, int ins = 0); // a pseudonym to insert a value inline name* insert(char* s) { return look(s, 1); } #endif /* TABLE_H */ !EOF! ls -l table.h echo x - tmp.c sed 's/^X//' > tmp.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include main() { char ch; for (int i = 0; i++ < 4; ) { if (cin.get(ch)) cout << "cin returned 1\n"; else cout << "cin returned 0\n"; cout << "ch = " << oct(ch) << "\n"; if (cin) cout << "cin is still 1\n"; else cout << "cin is still 0\n"; } } !EOF! ls -l tmp.c echo x - tmp2.c sed 's/^X//' > tmp2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include main() { char ch; if (cin.get(ch)) { cout << "got char " << dec(ch) << ", & putback\n"; cin.putback(ch); for (int i = 0; i < 3; i++) if (cin.get(ch)) cout << "got char " << dec(ch) << "\n"; else cout << "didn't get char\n"; } return 0; } !EOF! ls -l tmp2.c echo x - tmp2.in sed 's/^X//' > tmp2.in << '!EOF!' !EOF! ls -l tmp2.in echo x - tmp3.c sed 's/^X//' > tmp3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* <> */ /* < in.c */ int *_new (); int _delete (); int *_vec_new (); int _vec_delete (); extern char _ctype []; extern int toupper (); extern int tolower (); struct _iobuf { /* sizeof = 16 */ int __iobuf__cnt ; unsigned char *__iobuf__ptr ; unsigned char *__iobuf__base ; char __iobuf__flag ; char __iobuf__file ; } ; extern struct _iobuf _iob [20]; extern int _flsbuf (); extern int _filbuf (); extern struct _iobuf *fopen (); extern struct _iobuf *fdopen (); extern struct _iobuf *freopen (); extern long ftell (); extern char *fgets (); extern char *gets (); extern int puts (); extern int fputs (); extern int printf (); extern int fprintf (); extern int sprintf (); extern int scanf (); extern int fscanf (); extern int sscanf (); extern int fread (); extern int fwrite (); extern int fclose (); extern int fflush (); extern int clearerr (); extern int fseek (); extern int rewind (); extern int getw (); extern int fgetc (); extern struct _iobuf *popen (); extern int pclose (); extern int putw (); extern int fputc (); extern int setbuf (); extern int ungetc (); extern int exit (); extern int abort (); extern int atoi (); extern double atof (); extern long atol (); extern struct _iobuf *tmpfile (); extern char *ctermid (); extern char *cuserid (); extern char *tempnam (); extern char *tmpnam (); extern int perror (); extern int errno ; extern char *sys_errlist []; extern int sys_nerr ; extern unsigned char *_bufendtab []; /* enum state_value */ /* enum open_mode */ struct streambuf { /* sizeof = 28 */ char *_streambuf_base ; char *_streambuf_pptr ; char *_streambuf_gptr ; char *_streambuf_eptr ; char _streambuf_alloc ; struct _iobuf *_streambuf_fp ; int (**_streambuf__vptr )(); } ; int _streambuf_overflow (); int _streambuf_underflow (); static int (*streambuf__vtbl[])() = { (int(*)()) _streambuf_overflow , (int(*)()) _streambuf_underflow , 0}; int _streambuf_doallocate (); /* overload _ctor: */ extern int close (); struct filebuf { /* sizeof = 36 */ char *_streambuf_base ; char *_streambuf_pptr ; char *_streambuf_gptr ; char *_streambuf_eptr ; char _streambuf_alloc ; struct _iobuf *_streambuf_fp ; int (**_streambuf__vptr )(); int _filebuf_fd ; char _filebuf_opened ; } ; int _filebuf_overflow (); int _filebuf_underflow (); static int (*filebuf__vtbl[])() = { (int(*)()) _filebuf_overflow , (int(*)()) _filebuf_underflow , 0 }; struct filebuf *_filebuf_open (); /* overload _ctor: */ struct circbuf { /* sizeof = 28 */ char *_streambuf_base ; char *_streambuf_pptr ; char *_streambuf_gptr ; char *_streambuf_eptr ; char _streambuf_alloc ; struct _iobuf *_streambuf_fp ; int (**_streambuf__vptr )(); } ; int _circbuf_overflow (); int _circbuf_underflow (); static int (*circbuf__vtbl[])() = { (int(*)()) _circbuf_overflow , (int(*)()) _circbuf_underflow , 0 }; struct whitespace { /* sizeof = 4 */ char _dummy; } ; extern char *oct (); extern char *dec (); extern char *hex (); extern char *chr (); extern char *str (); extern char *form (); struct ostream { /* sizeof = 8 */ struct streambuf *_ostream_bp ; short _ostream_state ; } ; /* overload _lshift: */ struct ostream *_ostream__lshiftFPC__ (); struct ostream *_ostream__lshiftFL__ (); struct ostream *_ostream__lshiftFD__ (); struct ostream *_ostream__lshiftFRCstreambuf___ (); struct ostream *_ostream__lshiftFRCwhitespace___ (); struct ostream *_ostream__lshiftFRCcommon___ (); struct ostream *_ostream_put (); /* overload _ctor: */ struct istream { /* sizeof = 12 */ struct streambuf *_istream_bp ; struct ostream *_istream_tied_to ; char _istream_skipws ; short _istream_state ; } ; /* overload _rshift: */ struct istream *_istream__rshiftFPC__ (); struct istream *_istream__rshiftFRC__ (); struct istream *_istream__rshiftFRS__ (); struct istream *_istream__rshiftFRI__ (); struct istream *_istream__rshiftFRL__ (); struct istream *_istream__rshiftFRF__ (); struct istream *_istream__rshiftFRD__ (); struct istream *_istream__rshiftFRCstreambuf___ (); struct istream *_istream__rshiftFRCwhitespace___ (); struct istream *_istream__rshiftFRCcommon___ (); /* overload get: */ struct istream *_istream_getFPC_I_I__ (); struct istream *_istream_getFRCstreambuf__I__ (); struct istream *_istream_putback (); /* overload _ctor: */ extern int eatwhite (); extern struct istream cin ; extern struct ostream cout ; extern struct ostream cerr ; extern struct whitespace WS ; struct common { /* sizeof = 4 */ int (**_common__vptr )(); } ; static int _common_cmp (); static int _common__eq (); static char *_common_swho (); static int _common_iwho (); static int _common_size (); static struct ostream *_common_write (); static struct istream *_common_read (); static int (*common__vtbl[])() = { (int(*)()) _common_cmp , (int(*)()) _common__eq , (int(*)()) _common_swho , (int(*)()) _common_iwho , (int(*)()) _common_size , (int(*)()) _common_write , (int(*)()) _common_read , 0 }; struct filebuf cin_file ; struct istream cin ; struct whitespace WS ; extern int eatwhite (is ) struct istream *is ; { register struct streambuf *nbp ; register char c ; struct streambuf *_X_K1_flush_ostream ; if ((*is ). _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)(*is ). _istream_tied_to )-> _ostream_bp; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1); ((struct ostream *)(*is ). _istream_tied_to ) ; } nbp = (*is ). _istream_bp ; c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= ((struct streambuf *)nbp )-> _streambuf_pptr ) ? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))(((struct streambuf *)nbp )) : ((*((struct streambuf *)nbp )-> _streambuf_gptr )& 0377 )) ; while (((_ctype + 1 )[c ])& 010 ) c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 )) ? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ; if (c == -1) (*is ). _istream_state |= 1; } struct istream *_istream__rshiftFRCwhitespace___ (this , _A2 ) register struct istream *this ; struct whitespace *_A2 ; { register struct streambuf *nbp ; register int c ; struct streambuf *_X_K1_flush_ostream ; nbp = this -> _istream_bp ; if (this -> _istream_state ) return (struct istream *)this ; if (this -> _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1) ; ((struct ostream *)this -> _istream_tied_to ) ; } c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= ((struct streambuf *)nbp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*((struct streambuf *)nbp )-> _streambuf_gptr )& 0377 )) ; while (((_ctype + 1 )[c ])& 010 ) c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ; if (c == -1) this -> _istream_state |= 1; return (struct istream *)this ; } struct istream *_istream__rshiftFRC__ (this , s ) register struct istream *this ; register char *s ; { register int c ; struct streambuf *_X_K1_flush_ostream ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1) ; (struct ostream *)this -> _istream_tied_to ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } c = ( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= ((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr )& 0377 )) ; if (c == -1){ this -> _istream_state |= 3; return (struct istream *)this ; } if (( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 )) == -1) this -> _istream_state |= 1; (*s )= c ; return (struct istream *)this ; } struct istream *_istream__rshiftFPC__ (this , s ) register struct istream *this ; register char *s ; { register struct streambuf *nbp ; register int c ; struct streambuf *_X_K1_flush_ostream ; nbp = this -> _istream_bp ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1) ; ((struct ostream *)this -> _istream_tied_to ); } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= ((struct streambuf *)nbp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*((struct streambuf *)nbp )-> _streambuf_gptr )& 0377 )) ; if (c == -1) this -> _istream_state |= 2; while ((! (((_ctype + 1 )[c ])& 010 ))&& (c != -1)){ (*(s ++ ))= c ; if (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 )) c = (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )); else c = ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 ); } (*s )= '\0' ; if (c == -1) this -> _istream_state |= 1; return (struct istream *)this ; } struct istream *_istream__rshiftFRL__ (this , i ) register struct istream *this ; long *i ; { register int c ; register int ii ; register struct streambuf *nbp ; int neg ; struct streambuf *_X_K1_flush_ostream ; ii = 0 ; nbp = this -> _istream_bp ; neg = 0 ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1) ; ((struct ostream *)this -> _istream_tied_to ) ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } switch (c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= ((struct streambuf *)nbp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*((struct streambuf *)nbp )-> _streambuf_gptr )& 0377 )) ){ case '-' : case '+' : neg = c ; c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ; break ; case -1: this -> _istream_state |= 2; } if (((_ctype + 1 )[c ])& 04 ){ do { ii = (((ii * 10 )+ c )- '0' ); } while (((_ctype + 1 )[c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ])& 04 ); (*i )= ((neg == '-' )? (- ii ): ii ); } else this -> _istream_state |= 2; if (c == -1) this -> _istream_state |= 1; return (struct istream *)this ; } struct istream *_istream__rshiftFRI__ (this , i ) register struct istream *this ; int *i ; { long l ; struct streambuf *_X_K1_flush_ostream ; struct istream *_Xthis__OPV_istream ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { _X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ; (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1) ; (struct ostream *)this -> _istream_tied_to ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } if (( (_Xthis__OPV_istream = (struct istream *)_istream__rshiftFRL__ ( this , (long *)(& l )) ), ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) ) ) { (*i )= l ; } return (struct istream *)this ; } struct istream *_istream__rshiftFRS__ (this , i ) register struct istream *this ; short *i ; { long l ; struct streambuf *_X_K1_flush_ostream ; struct istream *_Xthis__OPV_istream ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { (_X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ); (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1); ((struct ostream *)this -> _istream_tied_to ) ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } if (( (_Xthis__OPV_istream = (struct istream *)_istream__rshiftFRL__ ( this , (long *)(& l )) ), ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) ) ){ (*i )= l ; } return (struct istream *)this ; } struct istream *_istream__rshiftFRD__ (this , d ) register struct istream *this ; double *d ; { register int c ; char buf [256]; register char *p ; register struct streambuf *nbp ; struct streambuf *_X_K1_flush_ostream ; c = 0 ; p = buf ; nbp = this -> _istream_bp ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { (_X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ); (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1); ((struct ostream *)this -> _istream_tied_to ) ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } switch (c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= ((struct streambuf *)nbp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*((struct streambuf *)nbp )-> _streambuf_gptr )& 0377 )) ){ case -1: this -> _istream_state = 3; return (struct istream *)this ; case '-' : case '+' : (*(p ++ ))= c ; c = ( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 )) ; } while (((_ctype + 1 )[c ])& 04 ){ (*(p ++ ))= c ; if (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 )) c = (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )); else c = ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 ); } if (c == '.' ){ do { (*(p ++ ))= c ; c = ( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 )) ; } while (((_ctype + 1 )[c ])& 04 ); } if ((c == 'e' )|| (c == 'E' )){ (*(p ++ ))= c ; switch (c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ){ case -1: this -> _istream_state = 3; return (struct istream *)this ; case '-' : case '+' : (*(p ++ ))= c ; c = ( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 )) ; } while (((_ctype + 1 )[c ])& 04 ){ (*(p ++ ))= c ; if (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= (((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr - 1 )) c = (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )); else c = ((*(++ ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))& 0377 ) ; } } (*p )= 0 ; (*d )= atof ( (char *)buf ) ; if (c == -1) this -> _istream_state |= 1; return (struct istream *)this ; } struct istream *_istream__rshiftFRF__ (this , f ) register struct istream *this ; float *f ; { double d ; struct streambuf *_X_K1_flush_ostream ; struct istream *_Xthis__OPV_istream ; if (this -> _istream_skipws ) eatwhite ( (struct istream *)this ) ; else if (this -> _istream_tied_to ) { (_X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ); (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1); ((struct ostream *)this -> _istream_tied_to ) ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } if (( (_Xthis__OPV_istream = (struct istream *)_istream__rshiftFRD__ ( this , (double *)(& d )) ), ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) ) ){ (*f )= d ; } return (struct istream *)this ; } struct istream *_istream_getFPC_I_I__ (this , s , len , term ) register struct istream *this ; register char *s ; register int len ; register char term ; { register int c ; register struct streambuf *nbp ; struct streambuf *_X_K1_flush_ostream ; nbp = this -> _istream_bp ; if (this -> _istream_tied_to ) { (_X_K1_flush_ostream = ((struct ostream *)this -> _istream_tied_to )-> _ostream_bp ); (*(((int (*)())(*_X_K1_flush_ostream -> _streambuf__vptr ))))( _X_K1_flush_ostream , -1); ((struct ostream *)this -> _istream_tied_to ) ; } if (this -> _istream_state ){ this -> _istream_state |= 2; return (struct istream *)this ; } if ((c = ( (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr >= ((struct streambuf *)this -> _istream_bp )-> _streambuf_pptr )? (*(((int (*)())(((struct streambuf *)this -> _istream_bp )-> _streambuf__vptr [1]))))( ((struct streambuf *)this -> _istream_bp )) : ((*((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr )& 0377 )) )== -1){ this -> _istream_state |= 3; return (struct istream *)this ; } while (((c != term )&& (c != -1))&& (len > 1 )){ (*(s ++ ))= c ; c = ( (((struct streambuf *)nbp )-> _streambuf_gptr >= (((struct streambuf *)nbp )-> _streambuf_pptr - 1 ))? (*(((int (*)())(((struct streambuf *)nbp )-> _streambuf__vptr [1]))))( ((struct streambuf *)nbp )) : ((*(++ ((struct streambuf *)nbp )-> _streambuf_gptr ))& 0377 )) ; len -- ; } (*s )= '\0' ; if (c == -1) this -> _istream_state |= 1; return (struct istream *)this ; } struct istream *_istream_putback (this , c ) register struct istream *this ; register char c ; { if (((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr > ((struct streambuf *)this -> _istream_bp )-> _streambuf_base ) ((*(-- ((struct streambuf *)this -> _istream_bp )-> _streambuf_gptr ))= c ); this -> _istream_state &= -2; return (struct istream *)this ; } static struct istream *_common_read (this , s ) register struct common *this ; struct istream *s ; { return s ; } static struct ostream *_common_write (this , s ) register struct common *this ; struct ostream *s ; { return s ; } static int _common_size (this ) register struct common *this ; { return 4; } static int _common_iwho (this ) register struct common *this ; { return (int )0 ; } static char *_common_swho (this ) register struct common *this ; { return (char *)0 ; } static int _common__eq (this , oo ) register struct common *this ; struct common *oo ; { return (this == (struct common *)(oo )); } static int _common_cmp (this , oo ) register struct common *this ; struct common *oo ; { return (this == (struct common *)(oo )); } /* the end */ /* <> */ /* < tmp2.c */ int main () { char ch ; int _Xos_getFRC___istream ; struct istream *_Xthis__OPV_istream ; _main(); _Xthis__OPV_istream = (struct istream *)( (_Xos_getFRC___istream = ((struct istream *)(& cin ))-> _istream_skipws ), ( (((struct istream *)(& cin ))-> _istream_skipws = 0 ), ( _istream__rshiftFRC__ ( ((struct istream *)(& cin )), ((char *)(& ch ))) , ( (((struct istream *)(& cin ))-> _istream_skipws = _Xos_getFRC___istream ), ((struct istream *)(& cin ))) ) ) ); if ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) { _ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( & cout , (char *)"got char ") , (char *)dec ( (long )ch , (int )0 ) ) , (char *)"\n") ; _istream_putback ( & cin , ch ) ; _Xthis__OPV_istream = (struct istream *)( (_Xos_getFRC___istream = ((struct istream *)(& cin ))-> _istream_skipws ), ( (((struct istream *)(& cin ))-> _istream_skipws = 0 ), ( _istream__rshiftFRC__ ( ((struct istream *)(& cin )), ((char *)(& ch ))) , ( (((struct istream *)(& cin ))-> _istream_skipws = _Xos_getFRC___istream ), ((struct istream *)(& cin ))) ) ) ); if ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) _ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( & cout , (char *)"got char ") , (char *)dec ( (long )ch , (int )0 ) ) , (char *)"\n") ; else _ostream__lshiftFPC__ ( & cout , (char *)"didn't get char\n") ; _Xthis__OPV_istream = (struct istream *)( (_Xos_getFRC___istream = ((struct istream *)(& cin ))-> _istream_skipws ), ( (((struct istream *)(& cin ))-> _istream_skipws = 0 ), ( _istream__rshiftFRC__ ( ((struct istream *)(& cin )), ((char *)(& ch ))) , ( (((struct istream *)(& cin ))-> _istream_skipws = _Xos_getFRC___istream ), ((struct istream *)(& cin ))) ) ) ); if ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) _ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( & cout , (char *)"got char ") , (char *)dec ( (long )ch , (int )0 ) ) , (char *)"\n") ; else _ostream__lshiftFPC__ ( & cout , (char *)"didn't get char\n") ; _Xthis__OPV_istream = (struct istream *)( (_Xos_getFRC___istream = ((struct istream *)(& cin ))-> _istream_skipws ), ( (((struct istream *)(& cin ))-> _istream_skipws = 0 ), ( _istream__rshiftFRC__ ( ((struct istream *)(& cin )), ((char *)(& ch ))) , ( (((struct istream *)(& cin ))-> _istream_skipws = _Xos_getFRC___istream ), ((struct istream *)(& cin ))) ) ) ); if ( (1< _Xthis__OPV_istream -> _istream_state )? (((struct istream *)0 )): _Xthis__OPV_istream ) _ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( (struct ostream *)_ostream__lshiftFPC__ ( & cout , (char *)"got char ") , (char *)dec ( (long )ch , (int )0 ) ) , (char *)"\n") ; else _ostream__lshiftFPC__ ( & cout , (char *)"didn't get char\n") ; } return (int )0 ; } /* the end */ !EOF! ls -l tmp3.c echo x - tmp4.c sed 's/^X//' > tmp4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /*ident "@(#)cfront:lib/stream/in.c 1.4" */ /* C++ stream i/o source in.c */ #include #include "stream.h" #include filebuf cin_file(stdin); // UNIX input stream 0 istream cin(&cin_file,1,&cout); // cin tied to cout /* predefined whitespace */ whitespace WS; /*inline */void eatwhite (istream& is) { if (is.tied_to) is.tied_to->flush(); register streambuf *nbp = is.bp; register char c = nbp->sgetc(); while (isspace(c)) c = nbp->snextc(); if (c == EOF) is.state |= _eof; } istream& istream::operator>>(whitespace&) { register streambuf *nbp = bp; if (state) return *this; if (tied_to) tied_to->flush(); register c = nbp->sgetc(); while (isspace(c)) c = nbp->snextc(); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register char& s) /* reads characters NOT very small integers */ { if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } register c = bp->sgetc(); if (c == EOF) { state |= _fail|_eof; return *this; } if (bp->snextc() == EOF) state |= _eof; s = c; return *this; } istream& istream::operator>>(register char* s) { register streambuf *nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get string */ register c = nbp->sgetc(); if (c == EOF) state |= _fail; while (!isspace(c) && c != EOF) { *s++ = c; c = nbp->snextc(); } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(long& i) { register c; register ii = 0; register streambuf *nbp = bp; int neg = 0; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } switch (c = nbp->sgetc()) { case '-': case '+': neg = c; c = nbp->snextc(); break; case EOF: state |= _fail; } if (isdigit(c)) { do { ii = ii*10+c-'0'; } while (isdigit(c=nbp->snextc())); i = (neg=='-') ? -ii : ii; } else state |= _fail; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(int& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = l; } return *this; } istream& istream::operator>>(short& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = l; } return *this; } istream& istream::operator>>(double& d) /* {+|-} d* {.} d* { e|E {+|-} d+ } except that - a dot must be pre- or succeded by at least one digit - an exponent must be preseded by at least one digit */ { register c = 0; char buf[256]; register char* p = buf; register streambuf* nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get the sign */ switch (c = nbp->sgetc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } /* get integral part */ while (isdigit(c)) { *p++ = c; c = bp->snextc(); } /* get fraction */ if (c == '.') { do { *p++ = c; c = bp->snextc(); } while (isdigit(c)); } /* get exponent */ if (c == 'e' || c == 'E') { *p++ = c; switch (c = nbp->snextc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } while (isdigit(c)) { *p++ = c; c = bp->snextc(); } } *p = 0; d = atof(buf); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(float& f) { double d; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>d ) { f = d; } return *this; } istream& istream::get( register char* s, /* character array to read into */ register int len, /* size of character array */ register char term /* character that terminates input */ ) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF && len > 1) { *s++ = c; c = nbp->snextc(); len--; } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::putback(register char c) { bp->sputbackc(c); state &= ~_eof; return *this; } istream& istream::get( register streambuf &s, /* streambuf to input to */ register char term /* termination character */ ){ register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register streambuf &s) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(common& p) { if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); return p.read(*this); } int doget(char &ch) { int ret = 0; if (cin.get(ch)) ret = 1; return ret; } main() { char ch; if (doget(ch)) { printf("got char %d\n", ch); cin.putback(ch); if (doget(ch)) printf("got char %d\n", ch); else printf("didn't get char\n"); if (doget(ch)) printf("got char %d\n", ch); else printf("didn't get char\n"); if (doget(ch)) printf("got char %d\n", ch); else printf("didn't get char\n"); } return 0; } !EOF! ls -l tmp4.c echo x - tst.c sed 's/^X//' > tst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include !EOF! ls -l tst.c echo x - tst.in sed 's/^X//' > tst.in << '!EOF!' X.NC 4 "Functions and Files" # function foo and bar X.XS 4.1 1 # arguments this and that # that those Write declarations for the following: a function taking arguments of type pointer to character and reference to integer and returning no value; a pointer to such a function; a function taking such a pointer as an argumnt; and a function returning such a pointer. Write the definition of a function that takes such a pointer as argument and returns its argument as the return value. Hint: use X.CW typedef . X.XE The first typedef should declare a name for the type "void function taking an argument of pointer to character and an argument of a reference to integer". The name of X.CW vf_pc_ri has been chosen because its letters are suggestive of the types of the return value and the arguments. This typedef looks like: X.Cs typedef void (*vf_pc_ri)(char *, int&); X.Ce X.P The second typedef declares a pointer to such a function pointer. Its name, X.CW p_vf_pc_ri , also is suggestive of the types which make up its collective type. This typedef looks like: X.Cs typedef vf_pc_ri *p_vf_pc_ri; X.Ce With these definitions on hand, the declarations are much easier: X.P A function taking arguments of type pointer to character and reference to integer and returning no value: X.Cs extern vf_pc_ri funca; X.Ce X.P A pointer to such a function: X.Cs extern p_vf_pc_ri ptra; X.Ce X.P A function taking such a pointer as an argumnt: X.Cs extern void funcb(p_vf_pc_ri); X.Ce X.P A function returning such a pointer: X.Cs extern p_vf_pc_ri funcc(); X.Ce X.P A function that takes such a pointer as argument and returns its argument as the return value might look like: X.Cs p_vf_pc_ri funcd(p_vf_pc_ri a) { return a; } X.Ce X.XS 4.2 1 What does the following mean? What would it be good for? X.Cs typedef int (rifii&) (int, int); X.Ce X.XE This is a typedef for a function which returns a reference to an integer. It takes two arguments, each of which is also an integer. It might be used for a function which is emulating a doubly dimensioned array. The two arguments would then be the indices into the array. A reference to the integer must be returned so that the function call can be used on the left side of an assignment operator as well as on the right side. X.XS 4.3 1.5 Write a program like "Hello, world" that takes a name as a command line argument and writes "Hello, !EOF! ls -l tst.in echo x - tst2.c sed 's/^X//' > tst2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include !EOF! ls -l tst2.c echo x - tst2.in sed 's/^X//' > tst2.in << '!EOF!' X.NC 4 "Functions and Files" # function foo and bar X.XS 4.1 1 # arguments this and that # that those Write declarations for the following:# xyz(a,b) make a and b go away a function taking arguments of type pointer to character and reference to integer and returning no value; a pointer to such a function; xyz(foo bar, bar foo) a function taking such a pointer as an argumnt;xyz(arguments, decisions) and a function returning such a pointer. Write the definition of a function that takes such a pointer as argument and returns its argument as the return value. Hint: use X.CW typedef . X.XE The first typedef should declare a name for the type "void function taking an argument of pointer to character and an argument of a reference to integer". The name of X.CW vf_pc_ri has been chosen because its letters are suggestive of the types of the return value and the arguments. This typedef looks like: X.Cs typedef void (*vf_pc_ri)(char *, int&); X.Ce X.P The second typedef declares a pointer to such a function pointer. Its name, X.CW p_vf_pc_ri , also is suggestive of the types which make up its collective type. This typedef looks like: X.Cs typedef vf_pc_ri *p_vf_pc_ri; X.Ce With these definitions on hand, the declarations are much easier: X.P A function taking arguments of type pointer to character and reference to integer and returning no value: X.Cs extern vf_pc_ri funca; X.Ce X.P A pointer to such a function: X.Cs extern p_vf_pc_ri ptra; X.Ce X.P A function taking such a pointer as an argumnt: X.Cs extern void funcb(p_vf_pc_ri); X.Ce X.P A function returning such a pointer: X.Cs extern p_vf_pc_ri funcc(); X.Ce X.P A function that takes such a pointer as argument and returns its argument as the return value might look like: X.Cs p_vf_pc_ri funcd(p_vf_pc_ri a) { return a; } X.Ce X.XS 4.2 1 What does the following mean? What would it be good for? X.Cs typedef int (rifii&) (int, int); X.Ce X.XE This is a typedef for a function which returns a reference to an integer. It takes two arguments, each of which is also an integer. It might be used for a function which is emulating a doubly dimensioned array. The two arguments would then be the indices into the array. A reference to the integer must be returned so that the function call can be used on the left side of an assignment operator as well as on the right side. X.XS 4.3 1.5 Write a program like "Hello, world" that takes a name as a command line argument and writes "Hello, !EOF! ls -l tst2.in echo x - tst3.in sed 's/^X//' > tst3.in << '!EOF!' X.NC 4 # function foo and bar a function taking arguments# bar jack and bar integer function and returning no value;# foo foofoo a pointer to such a function; a function taking such a pointer as an argumnt; !EOF! ls -l tst3.in echo x - tst4.in sed 's/^X//' > tst4.in << '!EOF!' x y !EOF! ls -l tst4.in echo x - tst5.in sed 's/^X//' > tst5.in << '!EOF!' x- !EOF! ls -l tst5.in # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0