Annotation of researchv10dc/vol2/cin/cin.m, revision 1.1.1.1

1.1       root        1: |make(rp)
                      2: 
                      3: |insert(../monk/monk.mac)
                      4: 
                      5: |comment(VOL2HEADER)|set_counter(page 325-1)|set_string(page_headers "'''")|set_string(even_headers "'The C Interpreter: A Tutorial for Cin Version 0.18''\f(NIcin\fP'")|set_string(odd_headers "'\f(NIcin\fP''The C Interpreter: A Tutorial for Cin Version 0.18'")|set_string(even_footers "_\\nP__UNIX Papers_")|set_string(odd_footers "'Research Tenth Edition''\\nP'")
                      6: 
                      7: |environment(computeroutput;
                      8:        verbatim on, file.information, line.spacing 1,
                      9:        fill off, size -1, space -1, font cw, blank.lines -1,
                     10:        tab.stops "\w'        'u 2u*\w'        'u 3u*\w'        'u 4u*\w'        'u 5u*\w'        'u 6u*\w'        'u 7u*\w'        'u 8u*\w'        'u 9u*\w'        'u 10u*\w'        'u 11u*\w'        'u";
                     11: 
                     12:        tab.stops, blank.lines -1, SPACE)
                     13: 
                     14: |author(name "T. J. Kowalski", initials TJK, location MH, department 11229,
                     15:        extension x2771, room 2C-568)
                     16: |document(number 11229-880606-07TMS, file_case 25952,
                     17:        work_program 311401-2199)
                     18: 
                     19: |author(name "H. H. Goguen", initials HHG, location MH, department 11229,
                     20:        extension x2771, room 2C-568)
                     21: |document(number 11229-880606-07TMS, file_case 25952,
                     22:        work_program 311401-2199)
                     23: 
                     24: |author(name "J. J. Puttress", initials JJP, location MH, department 11229,
                     25:        extension x7290, room 2C-577)
                     26: |document(number 11229-880606-07TMS, file_case 25952,
                     27:        work_program 311401-2199)
                     28: 
                     29: |date(June 6, 1988)
                     30: 
                     31: |title(The C Interpreter:
                     32: A Tutorial for Cin Version 0.18)
                     33: 
                     34: |begin(abstract)
                     35: The C interpreter, |i(cin), is the core of an interactive programming environment for
                     36: the C programming language.
                     37: We believe that by providing integrated facilities to create,
                     38: edit,
                     39: browse,
                     40: execute,
                     41: and debug programs,
                     42: this environment should enhance the productivity
                     43: of C programmers at |s(AT&T) and improve the quality of their code.
                     44: Furthermore,
                     45: we feel that |i(cin) provides an easy-to-use instructional environment.
                     46: |p
                     47: This memorandum is a tutorial guide to help users get started.
                     48: Although it does not cover everything,
                     49: it provides enough information for most users' daily needs.
                     50: Topics discussed include
                     51: creating simple programs,
                     52: testing individual functions and expressions,
                     53: inspecting and modifying variables,
                     54: using program views, and setting breakpoints.
                     55: |end(abstract)
                     56: 
                     57: |titlebox
                     58: 
                     59: |style(two_column)
                     60: 
                     61: |unnumbered_section(Introduction)
                     62: 
                     63: Interactive programming environments are common for |s(LISP),
                     64: |reference(Teitelman Masinter Interlisp Programming Environment)
                     65: |reference(Sandewall Programming in an Interactive Environment 1978)
                     66: |s(PASCAL),
                     67: |reference(Delisle Menicosy Schwartz Viewing a Programming Environment)
                     68: |reference(Reiss Graphical Program Development with PECAN)
                     69: |reference(Brown Sedgewick A System for Algorithm Animation)
                     70: |s(PL/C),
                     71: |reference(Archer Conway COPE: A Cooperative Programming Environment)
                     72: |reference(Teitelbaum Reps The Cornell Program Synthesizer 1981)
                     73: and Smalltalk.
                     74: |reference(Goldberg Robson Smalltalk-80: The Language and Its Implementation)
                     75: |reference(Tesler The Smalltalk Environment)
                     76: Some work has been done on various pieces of a C program environment, including
                     77: syntax directed editors,
                     78: |reference(Horgan Moore Techniques for Improving Language-Based Editors)
                     79: interpreters,
                     80: |reference(Saber-C 1988)
                     81: |reference(Feuer si - An Interpreter for the C Language)
                     82: |reference(Ostby A C interpreter)
                     83: debuggers,|reference(Adams Muchnick Dbxtool A Window-Based Symbolic Debugger)
                     84: |reference(Cargill The Feel of Pi)
                     85: and browsers.
                     86: |reference(Steffen Interactive Examination of a C Program with Cscope)
                     87: |p
                     88: |i(Cin) is a C interpreter: an interactive program
                     89: for creating, testing, modifying, and debugging a C program,
                     90: using directions provided by a user at a terminal.
                     91: The program can be a single function in a single file,
                     92: or a large collection of files and functions as in System 75.
                     93: |reference(System 75: Project Development Environment 1985)
                     94: |i(Cin) is part of the Integrated C Programming Environment,
                     95: |cw(cens),
                     96: currently being developed by Department 11229.
                     97: It implements correct full C,
                     98: enables rapid prototyping,
                     99: permits extensive error checking,
                    100: facilitates incremental update,
                    101: manages multiple software views,
                    102: and
                    103: provides a programmable command language.
                    104: |p
                    105: This tutorial is meant to simplify learning |i(cin).
                    106: We suggest that you read this document,
                    107: simultaneously using |i(cin) to follow the examples,
                    108: then read the manual page in the appendix
                    109: while continuing to experiment with |i(cin).
                    110: Furthermore,
                    111: we strongly recommend completing the exercises.
                    112: They both reinforce material covered in the text
                    113: and explore material not thoroughly discussed.
                    114: |p
                    115: This is an introduction and a tutorial.
                    116: For that reason,
                    117: no attempt is made to cover
                    118: more than a part of the facilities that |i(cin) offers
                    119: (although this fraction includes the most useful and frequently needed parts).
                    120: Explanations of the C language and the |s(UNIX)|sp(registered) system
                    121: are beyond the scope of this paper.
                    122: We assume that you know how to log on to a |s(UNIX) system
                    123: and how to express algorithms in C.
                    124: Information on both the |s(UNIX) system
                    125: and C is readily available from a variety of sources.
                    126: |reference(Kernighan Pike Prentice-Hall)
                    127: |reference(Kernighan Ritchie Prentice-Hall)
                    128: 
                    129: |section(Getting Started)
                    130: 
                    131: We'll assume you have logged in to a |s(UNIX) system
                    132: and have just received the shell prompt, e.g. ``$''.
                    133: The easiest way to start |i(cin) is to type
                    134: 
                    135: |begin(computeroutput)
                    136: |i($ )cin -i
                    137: |i(cin>)
                    138: |end(computeroutput)
                    139: 
                    140: You are now ready to go
                    141: |sp(Em dash) |i(cin) is waiting for your instructions.
                    142: |i(Cin) shows this by echoing a
                    143: 
                    144: |begin(computeroutput)
                    145: |i(cin>)
                    146: |end(computeroutput)
                    147: 
                    148: to your terminal.
                    149: Throughout this tutorial, responses from |i(cin) are in |i(italics).
                    150: |p
                    151: This section shows how to use the interactive mode of |i(cin),
                    152: that is, a mode where we can enter and execute programs interactively.
                    153: Later we'll talk about changing and debugging programs.
                    154: As our first problem,
                    155: let's leap the hurdle of creating, compiling, loading, and running
                    156: a program that prints ``hello, world'' on our terminal.
                    157: Though this is a painful task when we use the normal editor, compiler,
                    158: loader, and shell to run the program,
                    159: it's easy in |i(cin).
                    160: |p
                    161: When |i(cin) is started with the |cw(-i) option,
                    162: it is like working with a blank piece
                    163: of paper |sp(Em dash) there is no program or data present.
                    164: They must be supplied by the person using |i(cin).
                    165: The program,
                    166: with its data,
                    167: can be entered interactively
                    168: or read into |i(cin) from a file.
                    169: We will start by typing in a program
                    170: and return shortly to the reading of files.
                    171: |p
                    172: First a bit of terminology.
                    173: In |i(cin) jargon,
                    174: the program currently worked on is said to be
                    175: ``kept in the current |cw(view)''.
                    176: Think of the |cw(view) as a work space,
                    177: if you like,
                    178: or simply as the information that you are going to be
                    179: using.
                    180: The |cw(view) is like a piece of paper,
                    181: on which we will write things,
                    182: then change some of them,
                    183: and finally file the whole thing away for another day.
                    184: |p
                    185: The user tells |i(cin) what to do to the |cw(view)
                    186: by typing C expressions and declarations.
                    187: C expressions are executed immediately,
                    188: while declarations are stored in the |cw(view).
                    189: When an expression is executed,
                    190: |i(cin) uses both local and global variables.
                    191: |p
                    192: Now we're ready to solve our problem.
                    193: The easiest way is to write a C expression that calls the |cw(printf)
                    194: library routine.
                    195: 
                    196: |begin(computeroutput)
                    197: |i(cin>) printf("hello, world|sp(\)n");
                    198: |i(hello, world
                    199: cin>)
                    200: |end(computeroutput)
                    201: 
                    202: |p
                    203: Another way to solve our problem is to write a declaration for a |cw(main) function
                    204: and call it using a C expression.
                    205: 
                    206: |begin(computeroutput)
                    207: |i(cin>) void main()
                    208: {
                    209:   printf("hello, world|sp(\)n");
                    210: }
                    211: |i(cin>) main();
                    212: |i(hello, world
                    213: cin>)
                    214: |end(computeroutput)
                    215: 
                    216: |p
                    217: We draw your attention to the |cw(void main) declaration.
                    218: When you're in |i(cin)'s interactive mode,
                    219: you need to declare a return type for each function.
                    220: This allows |i(cin)'s interactive mode
                    221: to tell the difference between an expression calling |cw(main)
                    222: and a declaration of |cw(main).
                    223: Don't panic!
                    224: You don't have to change all your C programs.
                    225: This is only true when typing directly to interactive mode.
                    226: The normal default declaration, |cw(int), still applies when files are read in.
                    227: We could have designed |i(cin) to work like the
                    228: C interpreters referenced in the introduction, which require you to
                    229: type a special character to enter and leave a command mode,
                    230: but we felt that declaring a return type was more consistent with C syntax.
                    231: |p
                    232: You also saw that |i(cin) prompts only for a C expression
                    233: or a declaration.
                    234: Thus, there are no prompts for the function body of |cw(main).
                    235: This silence is preferred by experienced users,
                    236: but sometimes disturbs beginners.
                    237: |p
                    238: Finally finished with our problem, we'd like to return to our shell.
                    239: Exit |i(cin) by typing
                    240: 
                    241: |begin(computeroutput)
                    242: |i(cin>) cin_quit();
                    243: |i($)
                    244: |end(computeroutput)
                    245: 
                    246: or by typing the end-of-file character (hold the |s(CTRL) key down
                    247: and press |cw(d)).
                    248: 
                    249: |section(I Seemed To Have Confused It)
                    250: 
                    251: If you didn't get a ``hello, world'',
                    252: then |i(cin) is confused by the directions it got.
                    253: Let's look at some possible problems that may have occurred
                    254: and how to correct them.
                    255: |p
                    256: One possibility is
                    257: 
                    258: |begin(computeroutput)
                    259: |i($) cin -i
                    260: |i(cin: not found)
                    261: |i($)
                    262: |end(computeroutput)
                    263: 
                    264: The C interpreter, |i(cin), is not available on your system in the
                    265: directories specified by your |s(PATH) shell variable.
                    266: Please contact your system administrator.
                    267: If your system has |s(EXPTOOLS),
                    268: the administrator can get |i(cin) from Alan Hastings.
                    269: Otherwise,
                    270: your administrator can ask for |i(cin) by sending mail to |cw(research!frodo),
                    271: including his/her name,
                    272: department number,
                    273: telephone number,
                    274: location,
                    275: and room number.
                    276: |p
                    277: Another possibility is
                    278: 
                    279: |begin(computeroutput)
                    280: |i($) cin -i
                    281: |i(cin>) printff("hello, world|sp(\)n");
                    282: |i(interactive mode: 1: warning: 'printff' undefined
                    283: breakpoint in function 'cin_system'
                    284:  at line 1 of file 'interactive mode'
                    285: cin>)
                    286: |end(computeroutput)
                    287: 
                    288: |cw(printf) was misspelled.
                    289: Whenever |i(cin) encounters an undefined function or variable,
                    290: it recursively calls a breakpoint function, |cw(cin_system),
                    291: which places you in |i(cin)'s interactive mode waiting for input.
                    292: The simplest corrective action is to return and ignore the problem.
                    293: We can do this by typing
                    294: 
                    295: |begin(computeroutput)
                    296: |i(cin>) cin_return();
                    297: |i[interactive mode: 2: warning:
                    298:  call of undefined function (returning 0L)
                    299: cin>]
                    300: |end(computeroutput)
                    301: 
                    302: or by typing the end-of-file character.
                    303: This acts as if you decided to define a function, |cw(printff),
                    304: that returns a |cw(long) zero.
                    305: A future release of |i(cin) will allow you to modify the prompt to show
                    306: the number of recursive calls to |cw(cin_system).
                    307: Later we'll talk about additional corrective actions and
                    308: other predefined |cw(cin_) functions and variables.
                    309: |p
                    310: Yet another possibility is
                    311: 
                    312: |begin(computeroutput)
                    313: |i($) cin -i
                    314: |i(cin>) printf("hello, world|sp(\)n")
                    315: |end(computeroutput)
                    316: 
                    317: Neither ``hello, world'', nor the |cw(|i(cin>)) prompt appears.
                    318: You probably forgot to type the last semicolon (|cw(;)).
                    319: Even experienced users forget the terminating semicolon (|cw(;))
                    320: sometimes.
                    321: If |i(cin) seems to be ignoring you,
                    322: 
                    323: |begin(computeroutput)
                    324: |i($) cin -i
                    325: |i(cin>) printf("hello, world|sp(\)n);
                    326: |i(interactive mode: 1: newline in string)
                    327: |end(computeroutput)
                    328: 
                    329: type an extra line with just a semicolon (|cw(;)) on it,
                    330: or in some rare cases
                    331: 
                    332: |begin(computeroutput)
                    333: |i($) cin -i
                    334: |i(cin>) void main()
                    335: {
                    336:        printf("hello, world|sp(\)n);
                    337: }
                    338: |i(interactive mode: 3: newline in string
                    339: interactive mode: 4: syntax error
                    340:  in parameter list of function call)
                    341: |end(computeroutput)
                    342: 
                    343: an extra line with just a semicolon (|cw(;))
                    344: followed by an extra line with just a closing curly brace (|cw(})) on it.
                    345: Isn't error recovery wonderful!
                    346: The next release of |i(cin) will be more friendlier.
                    347: |p
                    348: Throughout the rest of the tutorial,
                    349: we will assume that our typing is perfect.
                    350: We use the |cw(samuel)|reference(Puttress 1986 browser)
                    351: editor to remember C statements and declarations in a scratch pad,
                    352: sending them to |i(cin) whenever we are happy with the syntax.
                    353: However, you can also remember and send
                    354: C statements and declarations with |cw(sam), |cw(jim), |cw(emacs), or |cw(inedit).
                    355: 
                    356: |subsection(Exercise 1)
                    357: 
                    358: Enter |i(cin) and use the formula |e<degree~ F ~=~ ( 9 / 5 ) ~*~ degree~ C ~+~ 32>
                    359: to create a conversion table from centigrade or Celsius temperatures to Fahrenheit
                    360: for 20|sp(degree) C to 30|sp(degree) C.
                    361: Do this exercise in two different ways:
                    362: |begin(number_list)
                    363: |item Write a C expression that calls the |cw(printf) library routine.
                    364: |item Declare a |cw(main) function and run it in |i(cin).
                    365: |end(number_list)
                    366: 
                    367: |section(Writing A Small Program)
                    368: 
                    369: Our next problem is to write a few routines to
                    370: print algebraic expression trees.
                    371: Let's start by declaring the template |cw(node) for our tree.
                    372: 
                    373: |begin(computeroutput)
                    374: |i(cin>) struct node {
                    375:   struct node *left;
                    376:   struct node *right;
                    377:   char *value;
                    378:   int type;
                    379: };
                    380: |i(cin>)
                    381: |end(computeroutput)
                    382: 
                    383: |p
                    384: The |cw(left) and |cw(right) fields are pointers to other |cw(node)s.
                    385: The |cw(value) field holds a character string representing
                    386: the operator, variable, or constant associated with the node.
                    387: The |cw(type) field shows the kind of operator,
                    388: variable, or constant held in |cw(value) field.
                    389: The allowable types are:
                    390: 
                    391: |begin(computeroutput)
                    392: |i(cin>) #define       ADD     1
                    393: #define        SUB     2
                    394: #define        MUL     3
                    395: #define        DIV     4
                    396: #define        EXPT    5
                    397: #define        UMINUS  6
                    398: #define        CONST   7
                    399: #define        VAR     8
                    400: |end(computeroutput)
                    401: 
                    402: |p
                    403: We'd like to pause and talk about prompts once again.
                    404: You're probably puzzled why there was only one |i(cin>) for the above set
                    405: of pre-processor statements.
                    406: Well,
                    407: in the 0.18 release |i(cin) prompts only for a C expression
                    408: or a declaration, and C pre-processor statements are a little different.
                    409: We think this is a botch and will change it in the next release,
                    410: but until then it's a feature.|dagnote(Features are
                    411: bugs that are not yet fixed.)
                    412: |p
                    413: Now that we have a data structure,
                    414: let's write a |cw(prt) routine to display the tree
                    415: in the format normally used for an equation.
                    416: This requires an in-order walk; in other words |sp(Em dash)
                    417: go left as far as you can,
                    418: print the node,
                    419: then go right as far as you can.
                    420: 
                    421: |begin(computeroutput)
                    422: |i(cin>) void
                    423: prt(n)
                    424: struct node *n;
                    425: {
                    426:   switch(n->type) {
                    427: 
                    428:   default:
                    429:     prt(n->left);
                    430:     printf("%s ", n->value);
                    431:     prt(n->right);
                    432:     break;
                    433: 
                    434:   case UMINUS:
                    435:     printf("%s ", n->value);
                    436:     prt(n->right);
                    437:     break;
                    438: 
                    439:   case CONST:
                    440:   case VAR:
                    441:     printf("%s ", n->value);
                    442:     break;
                    443: 
                    444:   }
                    445: }
                    446: |i(cin>)
                    447: |end(computeroutput)
                    448: 
                    449: |p
                    450: A powerful feature of |i(cin) enables a routine
                    451: to be tested as soon it is written.
                    452: This way you can make sure it does what you want
                    453: before incorporating it into a large program.
                    454: |i(Cin) also takes care of allocating and deallocating
                    455: data structures for testing.
                    456: |p
                    457: Let's test the |cw(prt) function.
                    458: First we'll include the standard I/O header file
                    459: so we can turn off output buffering.
                    460: 
                    461: |begin(computeroutput)
                    462: |i(cin>) #include <stdio.h>
                    463: |i(cin>) setbuf(stdout, NULL);
                    464: |i(cin>) setbuf(stderr, NULL);
                    465: |i(cin>)
                    466: |end(computeroutput)
                    467: 
                    468: Next we let |i(cin) allocate storage space for a sample node,
                    469: |cw(a1),
                    470: and set it to hold a constant, |cw(CONST), with a value of |cw(17).
                    471: Finally,
                    472: we call |cw(prt) and see it print |cw(17).
                    473: 
                    474: |begin(computeroutput)
                    475: |i(cin>) struct node a1;
                    476: |i(cin>) a1.type = CONST;
                    477: |i(cin>) a1.value = "17";
                    478: |i(cin>) prt(&a1);
                    479: |i(17 cin>)
                    480: |end(computeroutput)
                    481: 
                    482: For constants,
                    483: |cw(left) and |cw(right) are unused.
                    484: |p
                    485: It's likely that we'll want to save our work for later use.
                    486: A simple and easy way to do this
                    487: is to save an image of our program and data definitions as an executable file.
                    488: Let's do this by calling the predefined function |cw(cin_dump)
                    489: with the name of a file, |cw(./saved).
                    490: 
                    491: |begin(computeroutput)
                    492: |i(cin>) cin_dump("./saved");
                    493: |i(cin>) cin_quit();
                    494: |i($)
                    495: |end(computeroutput)
                    496: 
                    497: Any time afterwards we can invoke our saved executable and use the program
                    498: and data definitions we have just entered.
                    499: 
                    500: |begin(computeroutput)
                    501: |i($) ./saved
                    502: |i(cin>) prt(&a1);
                    503: |i(17 cin>)
                    504: |end(computeroutput)
                    505: 
                    506: This feature is useful for customizing our |i(cin) environment,
                    507: but in the 0.18 release of |i(cin) there is no way to print out
                    508: the definition of a given function.
                    509: We plan to enhance |i(cin) to do this in the future,
                    510: but for now we recommend using an editor to keep your functions
                    511: in files.
                    512: |p
                    513: Thus, we need to learn how to
                    514: load source or object files into |i(cin).
                    515: We'll assume you've returned to your shell,
                    516: placed the definition for |cw(node)
                    517: and its |cw(#define)s in |cw(node.h),
                    518: and placed |cw(#include "node.h")
                    519: along with the definition for |cw(prt) in |cw(prt.c).
                    520: |p
                    521: Now let's go back to |i(cin) and load in the |cw(prt) function.
                    522: 
                    523: |begin(computeroutput)
                    524: |i($) cin -i
                    525: |i(cin>) cin_load("prt.c");
                    526: |i(cin>)
                    527: |end(computeroutput)
                    528: 
                    529: |p
                    530: When |i(cin) loaded |cw(prt.c), it placed
                    531: the structure definition for |cw(node),
                    532: the |cw(#define)s,
                    533: and the definition for |cw(prt)
                    534: in a |cw(view) called |cw(prt.c).
                    535: A |cw(view) is the internal representation of a C source file |sp(Em dash)
                    536: |cw(#define)s, static variables and functions, and global declarations.
                    537: Outside |i(cin), the functions and data of a C program are packaged in a file;
                    538: inside |i(cin) they are contained in a |cw(view).
                    539: Earlier, when we typed declarations directly into the interpreter,
                    540: they were placed into a default |cw(view) called ``interactive mode''.
                    541: To use the declarations,
                    542: we need to be in the |cw(view) where they are stored.
                    543: So if we are sure we defined something, but |i(cin) can't find it,
                    544: we have probably gotten into the wrong |cw(view).
                    545: We can see what |cw(view)s are available by using the predefined function
                    546: |cw(cin_views), and we can change our |cw(view) by using |cw(cin_view).
                    547: 
                    548: |begin(computeroutput)
                    549: |i(cin>) cin_views();
                    550: |i(   prt.c
                    551:  |sp(*) interactive mode
                    552: cin>) cin_view("prt.c");
                    553: |i(cin>) cin_views();
                    554: |i( |sp(*) prt.c
                    555:    interactive mode
                    556: cin>)
                    557: |end(computeroutput)
                    558: 
                    559: |p
                    560: We have just seen that |cw(cin_views) marks our current |cw(view)
                    561: with an asterisk (|cw(*)).
                    562: Do not confuse the ``interactive mode'' session,
                    563: which is entered by typing |cw(cin -i),
                    564: with the default interactive mode |cw(view).
                    565: In interactive mode,
                    566: you may access any |cw(view)
                    567: and enter C expressions or declarations in the context of that |cw(view).
                    568: The interactive mode |cw(view) is simply the default |cw(view),
                    569: used for storing C declarations not associated with an external file.
                    570: |p
                    571: Let's use the declaration of |cw(struct node)
                    572: and the |cw(#define) for |cw(CONST) in the current or |cw(prt.c) |cw(view)
                    573: to initialize a |cw(struct node a1).
                    574: 
                    575: |begin(computeroutput)
                    576: |i(cin>) struct node a1;
                    577: |i(cin>) a1.type = CONST;
                    578: |i(cin>) a1.value = "17";
                    579: |i(cin>)
                    580: |end(computeroutput)
                    581: 
                    582: |p
                    583: Although we said our typing would be prefect,|dagnote(as you can see it's not)
                    584: let's see what happens if we make the common mistake of passing
                    585: a structure instead of a pointer to the structure.
                    586: 
                    587: |begin(computeroutput)
                    588: |i(cin>) prt(a1);
                    589: |i(prt.c: 7: null pointer access
                    590: breakpoint in function 'prt' at line 7 of file 'prt.c'
                    591: cin>)
                    592: |end(computeroutput)
                    593: 
                    594: |p
                    595: At this point we can escape to our shell and print a numbered listing
                    596: of |cw(prt.c).
                    597: 
                    598: |begin(computeroutput)
                    599: |i(cin>) system("pr -n -t prt.c");
                    600: |i[ 1  #include "node.h"
                    601:  2
                    602:  3     void
                    603:  4     prt(n)
                    604:  5     struct node |sp(*)n;
                    605:  6     {
                    606:  7       switch(n|cw(->)type) {
                    607:  8
                    608:  9       default:
                    609: 10         prt(n|cw(->)left);
                    610: 11         printf("%s ", n|cw(->)value);
                    611: 12         prt(n|cw(->)right);
                    612: 13         break;
                    613: 14
                    614: 15       case UMINUS:
                    615: 16         printf("%s ", n|cw(->)value);
                    616: 17         prt(n|cw(->)right);
                    617: 18         break;
                    618: 19
                    619: 20       case CONST:
                    620: 21       case VAR:
                    621: 22         printf("%s ", n|cw(->)value);
                    622: 23         break;
                    623: 24
                    624: 25       }
                    625: 26     }
                    626: cin>]
                    627: |end(computeroutput)
                    628: 
                    629: |p
                    630: By a quick process of elimination,
                    631: we realize that
                    632: |cw(n) must be our problem,
                    633: because line 7 only has one pointer variable.
                    634: When you are in a |i(cin) breakpoint function,
                    635: |i(cin) computes the value of expressions in the current execution context
                    636: |sp(Em dash) an expression is evaluated just as though
                    637: it were placed in the program source at the current point of execution.
                    638: Thus, we can check to see if |cw(n) is zero by printing its value.
                    639: 
                    640: |begin(computeroutput)
                    641: |i(cin>) printf("%d|sp(\)n", n);
                    642: |i(0)
                    643: |i(cin>)
                    644: |end(computeroutput)
                    645: 
                    646: |p
                    647: If we failed to notice our ``passing
                    648: a structure instead of a pointer to the structure'' typo,
                    649: we might think that |cw(prt) got into trouble because it called itself.
                    650: We can check this by using the predefined function |cw(cin_where).
                    651: 
                    652: |begin(computeroutput)
                    653: |i(cin>) cin_where();
                    654: |i{cin_system()   [prt.c:1]
                    655: prt(n = 0x0)   [prt.c:7]
                    656: cin_system()   [interactive mode:32]
                    657: cin>}
                    658: |end(computeroutput)
                    659: 
                    660: This tells us that we are currently in |i(cin)'s breakpoint function,
                    661: |cw(cin_system),
                    662: looking at a call of |cw(prt) that was made from
                    663: interactive mode.
                    664: Because there are not two calls to |cw(prt),
                    665: we are assured it didn't recursively call itself.
                    666: |p
                    667: As you can see from the reference to line number 32,
                    668: the authors need to struggle further with what line numbers should mean in
                    669: interactive mode.
                    670: In particular, |cw(cin_where) and |cw(cin_break),
                    671: discussed later,
                    672: don't seem to use sensible line numbers for functions defined in interactive mode.
                    673: |p
                    674: Let's fix the problem with |cw(n) by modifying its value to be
                    675: |cw(&a1) and allowing the program to continue.
                    676: 
                    677: |begin(computeroutput)
                    678: |i(cin>) n = &a1;
                    679: |i(cin>) cin_return();
                    680: |i(17 cin>)
                    681: |end(computeroutput)
                    682: 
                    683: Most debuggers don't permit you to continue after a serious error.
                    684: Whenever possible,
                    685: |i(cin) allows you to recover from an error
                    686: once you've taken corrective action.
                    687: If we don't want to take corrective action,
                    688: we can remove all calls of |i(cin)'s breakpoint function by calling |cw(exit).
                    689: 
                    690: |begin(computeroutput)
                    691: |i(cin>) exit(0);
                    692: |i(cin>)
                    693: |end(computeroutput)
                    694: 
                    695: Sometimes there is no way to fix the problem
                    696: and all we can do is |cw(cin_quit).
                    697: |p
                    698: Now let's define a function that creates a node,
                    699: placing the function in |cw(create.c).
                    700: We can enter our favorite editor by
                    701: 
                    702: |begin(computeroutput)
                    703: |i(cin>) system("${EDITOR-/bin/ed} foo.c");
                    704: |i(?foo.c)
                    705: |end(computeroutput)
                    706: 
                    707: and printing out our file
                    708: 
                    709: |begin(computeroutput)
                    710: |i(cin>) system("pr -n -t create.c");
                    711: |i[ 1  #include <stdio.h>
                    712:  2     #include "node.h"
                    713:  3
                    714:  4     struct node |sp(*)
                    715:  5     create(left, right, type, value)
                    716:  6     struct node |sp(*)left, |sp(*)right;
                    717:  7     char |sp(*)value;
                    718:  8     {
                    719:  9       struct node |sp(*)n;
                    720: 10       struct node |sp(*)memory();
                    721: 11
                    722: 12       if (n = memory(
                    723: 13        sizeof(struct node))) {
                    724: 14         n|cw(->)left = left;
                    725: 15         n|cw(->)right = right;
                    726: 16         n|cw(->)type = type;
                    727: 17         n|cw(->)value = value;
                    728: 18         return(n);
                    729: 19       }
                    730: 20
                    731: 21       fprintf(stderr,
                    732: 22        "No memory to create a node|sp(\)n");
                    733: 23       exit(1);
                    734: 24     }
                    735: cin>] cin_load("create.c");
                    736: |i[create.c: 8: warning: function 'create'
                    737: has implicit return and 'return e;' (line 18)
                    738: cin>]
                    739: |end(computeroutput)
                    740: 
                    741: |p
                    742: The error message warns us that the function |cw(create),
                    743: which is declared starting on line 8,
                    744: ends without returning a value.
                    745: This is fine, because the function |cw(exit)
                    746: would never let us get to the end of the routine.
                    747: |p
                    748: Now let's change our |cw(view) to the |cw(create.c) declarations,
                    749: make a few nodes, and print the expression tree
                    750: for |cw[2 * (17 - x)].
                    751: We can represent the expression tree graphically as
                    752: 
                    753: |begin(here)
                    754: |begin(picture)
                    755: scale=100
                    756: box invis ht 96 wid 144 with .sw at 0,0
                    757: "\fR\s10\&|sp(-) (t1)\f1\s0" at 122,42
                    758: "\fR\s10\&x (t3)\f1\s0" at 160,-10
                    759: "\fR\s10\&17 (t2)\f1\s0" at 80,-10
                    760: line from 104,40 to 144,0
                    761: line from 104,40 to 64,0
                    762: "\fR\s10\&2 (t5)\f1\s0" at 24,26
                    763: "\fR\s10\&|sp(*) (t4)\f1\s0" at 80,86
                    764: line from 64,80 to 104,40
                    765: line from 64,80 to 24,40
                    766: |end(picture)
                    767: |end(here)
                    768: 
                    769: where the labels in parentheses are the variable names for the |cw(struct node)
                    770: pointers
                    771: and the other symbols are the |cw(value)s for the |cw(node)s.
                    772: 
                    773: |begin(computeroutput)
                    774: |i(cin>) cin_view("create.c");
                    775: |i(cin>) struct node *t1, *t2, *t3;
                    776: |i(cin>) t3 = create((struct node *)0,
                    777: (struct node *)0, VAR, "x");
                    778: |i(create.c: 12: warning: 'memory' undefined
                    779: breakpoint in function 'create'
                    780: at line 12 of file 'create.c'
                    781: cin>)
                    782: |end(computeroutput)
                    783: 
                    784: |p
                    785: A common programming practice is to leave ``stubs'',
                    786: or functions to be defined at a later date.
                    787: |i(Cin) will stop when it encounters functions or variables that are not defined,
                    788: permitting you to define them.
                    789: Here |i(cin) has stopped because it can't find a definition for |cw(memory).
                    790: 
                    791: |begin(computeroutput)
                    792: |i(cin>) struct node *
                    793: memory(n)
                    794: unsigned n;
                    795: {
                    796:   struct node *malloc();
                    797:   return malloc(n);
                    798: }
                    799: |i(cin>) cin_return();
                    800: |i(cin>) t2 = create((struct node *)0,
                    801: (struct node *)0, CONST, "17");
                    802: |i(cin>) t1 = create(t2, t3, ADD, "+");
                    803: |i(cin>) struct node *t4, *t5;
                    804: |i(cin>) t5 = create((struct node *)0,
                    805: (struct node *)0, CONST, "2");
                    806: |i(cin>) t4 = create(t5, t1, MUL, "*");
                    807: |i(cin>) prt(t4);
                    808: |i(2 |sp(*) 17 + x cin>)
                    809: |end(computeroutput)
                    810: 
                    811: We'd like to emphasize that declarations can be mixed
                    812: with C expressions in interactive mode.
                    813: 
                    814: |subsection(Exercise 2)
                    815: 
                    816: Use |i(cin) and your favorite editor to enhance the |cw(prt) function
                    817: by adding parentheses to the output that show the nesting levels;
                    818: e.g., |cw<prt(t4)> should output |cw<( 2 * ( 17 + x ) )>.
                    819: 
                    820: |section(Debugging With Breakpoints)
                    821: 
                    822: We've already seen that any legal C expression can be used
                    823: when |i(cin) enters the breakpoint function,
                    824: but we haven't seen how to force |i(cin)
                    825: to enter a breakpoint function.
                    826: The easiest way is to use your editor and insert calls to the
                    827: predefined function |cw(cin_system) into your program.
                    828: 
                    829: |begin(computeroutput)
                    830: 1      hello()
                    831: 2      {
                    832: 3        int i;
                    833: 4        i = 17;
                    834: 5        printf("hello, %d", i);
                    835: 6        cin_system();
                    836: 7        printf("world %d times|sp(\)n", i);
                    837: 8      }
                    838: |end(computeroutput)
                    839: 
                    840: |p
                    841: So if we were to load in |cw(hello.c) and run it:
                    842: 
                    843: |begin(computeroutput)
                    844: cin> |i($) cin -i
                    845: |i(cin>) cin_load("hello.c");
                    846: |i(cin>) hello();
                    847: |i(breakpoint in function 'hello' at line 6 of file 'hello.c'
                    848: hello, 17cin>) i = 3;
                    849: |i(cin>) cin_return();
                    850: |i(world 3 times
                    851: cin>)
                    852: |end(computeroutput)
                    853: 
                    854: We'd be able to change the value of |cw(i),
                    855: or anything else, for that matter,
                    856: to whatever we want.
                    857: This is like placing |cw(printf)'s in our code that allow us
                    858: to print or modify anything.
                    859: |p
                    860: We can obtain a less permanent breakpoint using the predefined function
                    861: |cw(cin_break), and remove it using |cw(cin_unbreak).
                    862: Let's return to the original |cw(prt) routine contained in |cw(prt.c),
                    863: assert a breakpoint on line 7,
                    864: and run it with |cw(t4).
                    865: Because we've already debugged |cw(create) and |cw(memory),
                    866: we can use the C compiler to create object files for them,
                    867: continuing to debug |cw(prt) in source form.
                    868: By mixing object files with source files, we get the speed of compiled code
                    869: for functions that are debugged,
                    870: combined with the error checking of interpreted code
                    871: for functions we are testing.
                    872: 
                    873: |begin(computeroutput)
                    874: |i($) cc -O -c create.c memory.c
                    875: |i(create.c:
                    876: memory.c:
                    877: $) cin -i prt.c create.o memory.o
                    878: |i(cin>) cin_view("prt.c");
                    879: |i(cin>) struct node *t1, *t2, *t3;
                    880: |i(cin>) struct node *create();
                    881: |i(cin>) #include <stdio.h>
                    882: |i(cin>) t3 = create((struct node *)0,
                    883: (struct node *)0, VAR, "x");
                    884: |i(cin>) t2 = create((struct node *)0,
                    885: (struct node *)0, CONST, "17");
                    886: |i(cin>) t1 = create(t2, t3, ADD, "+");
                    887: |i(cin>) struct node *t4, *t5;
                    888: |i(cin>) t5 = create((struct node *)0,
                    889: (struct node *)0, CONST, "2");
                    890: |i(cin>) t4 = create(t5, t1, MUL, "*");
                    891: |i(cin>)
                    892: |end(computeroutput)
                    893: 
                    894: |p
                    895: |cw(Cin_break) and |cw(cin_unbreak) both require us to be in the
                    896: |cw(view) where the function is defined and restrict us to functions
                    897: that are being interpreted.
                    898: We plan to enhance |i(cin) to remove these restrictions in the future.
                    899: 
                    900: |begin(computeroutput)
                    901: |i(cin>) cin_break("prt", 7);
                    902: |i(breakpoint in function prt at line 7
                    903: cin>) prt(t4);
                    904: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
                    905: cin>) cin_return();
                    906: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
                    907: cin>) cin_return();
                    908: |i(breakpoint in function 'prt' at line 7 of file 'prt.c'
                    909: 2 |sp(*) cin>) cin_where();
                    910: |i{cin_system()   [prt.c:1]
                    911: prt(n = 0x9382C)   [prt.c:7]
                    912: prt(n = 0x93854)   [prt.c:12]
                    913: cin_system()   [stdio.h:50]
                    914: cin>} cin_unbreak("prt", 7);
                    915: |i(breakpoint removed from line 7 in prt
                    916: cin>) cin_return();
                    917: |i(17 + x cin>) cin_quit();
                    918: |i($)
                    919: |end(computeroutput)
                    920: 
                    921: We plan to enhance |i(cin) by adding another argument to |cw(cin_break).
                    922: This argument will be a string that is executed when the breakpoint function
                    923: is entered.
                    924: This will let us set breakpoints that remove themselves,
                    925: print interesting things,
                    926: or even set other breakpoints.
                    927: 
                    928: |section(Program Equals Data)
                    929: 
                    930: A common trick of interpreters,
                    931: especially in the |s(LISP) world,
                    932: is to use the same representation for data handled by a program
                    933: and the program text itself.
                    934: |p
                    935: As our last programming task in this tutorial,
                    936: let's write a simple desk calculator.
                    937: To accomplish this,
                    938: we need to read a string from the user,
                    939: wrap it in a |cw(printf) C expression,
                    940: and pass it to the predefined function |cw(cin_eval).
                    941: 
                    942: |begin(computeroutput)
                    943: |i($) cin -i -lm
                    944: |i(cin>) #include <stdio.h>
                    945: |i(cin>) #include <math.h>
                    946: |i(cin>) char buf[1024], buf2[1024];
                    947: |i(cin>) while(gets(buf) != NULL) {
                    948:   sprintf(buf2,
                    949:    "printf(|sp(\)"%%g|sp(\)|sp(\)n|sp(\)",(double)(%s));",
                    950:    buf);
                    951:   cin_eval(buf2);
                    952: }
                    953: sqrt(2.0) * sqrt(2.0)
                    954: |i(2)
                    955: |end(computeroutput)
                    956: 
                    957: In writing the |cw(printf) expression shown above,
                    958: the trickiest part was ensuring that the argument would be appropriate
                    959: to the |cw(g) format.
                    960: That's what the |cw<(double)> accomplished.
                    961: This example is also plagued with getting the right number of
                    962: |sp(\)s and |cw(%)s.
                    963: 
                    964: |subsection(Exercise 3)
                    965: 
                    966: Enhance the desk calculator C expression to remember the
                    967: last value as |cw(t)
                    968: and make it into a shell file that can be easily executed.
                    969: 
                    970: |section(Bugs)
                    971: 
                    972: |center(You find 'em.
                    973: We squash 'em!)
                    974: |p
                    975: The interactive mode is new with the 0.18 release of |i(cin).
                    976: It's hard to anticipate all the errors you may encounter,
                    977: and because of this we need your help to improve our tool.
                    978: Thus, we welcome bug reports sent to research!frodo.
                    979: Please include a short program along with the terminal input and
                    980: output that creates the |i(cin) problem.
                    981: 
                    982: |section(Summary Of Predefined Functions)
                    983: 
                    984: Several pre-defined functions are provided for the user,
                    985: where |i(name), |i(string), |i(file), |i(line), |i(func), |i(func_mod),
                    986: and |i(func_ref) are declared as:
                    987: 
                    988: |begin(computeroutput)
                    989: char *|i(name), *|i(string), *|i(file);
                    990: int |i(line);
                    991: long (*|i(func))(), (*|i(func_mod))(), (*|i(func_ref))();
                    992: |end(computeroutput)
                    993: 
                    994: |blank_space(-1)
                    995: |begin(computeroutput)
                    996: void cin_bind(|i(name), |i(func))
                    997: |end(computeroutput)
                    998: |blank_space(-1)
                    999: Set an alias of |i(name) for the function |i(func).
                   1000: 
                   1001: |begin(computeroutput)
                   1002: int cin_break(|i(name), |i(line))
                   1003: |end(computeroutput)
                   1004: |blank_space(-1)
                   1005: Set a breakpoint in function |i(name) at line number |i(line) in the current
                   1006: |cw(view).
                   1007: Returns 0 if breakpoint cannot be set.
                   1008: 
                   1009: |begin(computeroutput)
                   1010: int cin_dump(|i(name))
                   1011: |end(computeroutput)
                   1012: |blank_space(-1)
                   1013: Create an |cw(a.out) and place it in the file |i(name).
                   1014: Returns 0 if |i(name) cannot be created.
                   1015: 
                   1016: |begin(computeroutput)
                   1017: int cin_eval(|i(string))
                   1018: |end(computeroutput)
                   1019: |blank_space(-1)
                   1020: Execute the C statement |i(string)
                   1021: as if it were present in the program where the |cw(cin_eval) is located.
                   1022: Returns 0 if |i(string) could not be parsed.
                   1023: 
                   1024: |begin(computeroutput)
                   1025: int cin_load(|i(file))
                   1026: |end(computeroutput)
                   1027: |blank_space(-1)
                   1028: Load |i(file) into a new |cw(view),
                   1029: using the standard file-naming conventions for |i(cc)(1).
                   1030: Returns 0 if |i(file) can not be loaded.
                   1031: 
                   1032: |begin(computeroutput)
                   1033: void cin_return()
                   1034: |end(computeroutput)
                   1035: |blank_space(-1)
                   1036: Return from a breakpoint.
                   1037: 
                   1038: |begin(computeroutput)
                   1039: int cin_spy(|i(name), |i(func_mod), |i(func_ref))
                   1040: |end(computeroutput)
                   1041: |blank_space(-1)
                   1042: Call the function |i(func_mod) whenever the variable |i(name) is modified.
                   1043: Call the function |i(func_ref) whenever the variable |i(name) is referenced.
                   1044: Either |i(func_mod) or |i(func_ref) can be |cw<(long (*)())0>.
                   1045: Returns 0 if there are no spies active.
                   1046: 
                   1047: |begin(computeroutput)
                   1048: void cin_system()
                   1049: |end(computeroutput)
                   1050: |blank_space(-1)
                   1051: Enter ``interactive mode''.
                   1052: 
                   1053: |begin(computeroutput)
                   1054: int cin_unbreak(|i(name), |i(line))
                   1055: |end(computeroutput)
                   1056: |blank_space(-1)
                   1057: Remove a breakpoint in function |i(name) at line number |i(line) in the current
                   1058: |cw(view).
                   1059: Returns 0 if the breakpoint was not set.
                   1060: 
                   1061: |begin(computeroutput)
                   1062: int cin_view(|i(name))
                   1063: |end(computeroutput)
                   1064: |blank_space(-1)
                   1065: Change the current |cw(view) to |i(name).
                   1066: Returns 0 if the |cw(view) was not found.
                   1067: 
                   1068: |begin(computeroutput)
                   1069: void cin_views()
                   1070: |end(computeroutput)
                   1071: |blank_space(-1)
                   1072: Print the available |cw(view)s.
                   1073: The current |cw(view) is marked with an asterisk (|cw(*)).
                   1074: 
                   1075: |begin(computeroutput)
                   1076: void cin_whatis(|i(name))
                   1077: |end(computeroutput)
                   1078: |blank_space(-1)
                   1079: Print the type of the variable |i(name).
                   1080: 
                   1081: |begin(computeroutput)
                   1082: void cin_where()
                   1083: |end(computeroutput)
                   1084: |blank_space(-1)
                   1085: Print the trace of subroutine calls.
                   1086: 
                   1087: |begin(computeroutput)
                   1088: void cin_quit()
                   1089: |end(computeroutput)
                   1090: |blank_space(-1)
                   1091: Exit |i(cin).
                   1092: 
                   1093: |section(Summary Of Predefined Variables)
                   1094: 
                   1095: Several predefined variables are provided for the user.
                   1096: 
                   1097: |begin(computeroutput)
                   1098: extern char *cin_libpath
                   1099: |end(computeroutput)
                   1100: |blank_space(-1)
                   1101: A colon (|cw(:)) -separated list of libraries to search for undefined routines
                   1102: (defaults to libraries specified on the command line and
                   1103: ``|cw(-lc)'').
                   1104: 
                   1105: |begin(computeroutput)
                   1106: extern char *cin_prompt
                   1107: |end(computeroutput)
                   1108: |blank_space(-1)
                   1109: The ``interactive mode'' prompt (default ``|cw(cin>) '').
                   1110: 
                   1111: |section(Answers)
                   1112: 
                   1113: |subsection(Answer 1)
                   1114: 
                   1115: |blank_space(-1)
                   1116: |begin(computeroutput)
                   1117: |i($) cin -i
                   1118: |i(cin>) int i;
                   1119: |i(cin>) for (i = 20; i <= 30; ++i)
                   1120:  printf("%d %g|sp(\)n",
                   1121:   i, 9. / 5. * i + 32.);
                   1122: |i(20 68
                   1123: 21 69.8
                   1124: 22 71.6
                   1125: 23 73.4
                   1126: 24 75.2
                   1127: 25 77
                   1128: 26 78.8
                   1129: 27 80.6
                   1130: 28 82.4
                   1131: 29 84.2
                   1132: 30 86
                   1133: cin>) void main()
                   1134: {
                   1135:   int i;
                   1136: 
                   1137:   for (i = 20; i <= 30; ++i)
                   1138:    printf("%d %g|sp(\)n",
                   1139:      i, 9. / 5. * i + 32.);
                   1140: }
                   1141: |i(cin>) main();
                   1142: |i(20 68
                   1143: 21 69.8
                   1144: 22 71.6
                   1145: 23 73.4
                   1146: 24 75.2
                   1147: 25 77
                   1148: 26 78.8
                   1149: 27 80.6
                   1150: 28 82.4
                   1151: 29 84.2
                   1152: 30 86
                   1153: cin>) cin_quit();
                   1154: |i($)
                   1155: |end(computeroutput)
                   1156: |blank_space(-1)
                   1157: 
                   1158: |subsection(Answer 2)
                   1159: 
                   1160: |blank_space(-1)
                   1161: |begin(computeroutput)
                   1162: void
                   1163: prt(n)
                   1164: struct node *n;
                   1165: {
                   1166:   switch(n->type) {
                   1167: 
                   1168:   default:
                   1169:     printf("( ");
                   1170:     prt(n->left);
                   1171:     printf("%s ", n->value);
                   1172:     prt(n->right);
                   1173:     printf(") ");
                   1174:     break;
                   1175: 
                   1176:   case UMINUS:
                   1177:     printf("%s ", n->value);
                   1178:     prt(n->right);
                   1179:     break;
                   1180: 
                   1181:   case CONST:
                   1182:   case VAR:
                   1183:     printf("%s ", n->value);
                   1184:     break;
                   1185: 
                   1186:   }
                   1187: }
                   1188: |end(computeroutput)
                   1189: |blank_space(-1)
                   1190: 
                   1191: |subsection(Answer 3)
                   1192: 
                   1193: |blank_space(-1)
                   1194: |begin(computeroutput)
                   1195: (echo 'extern char *cin_prompt;
                   1196: cin_prompt="";
                   1197: #include <stdio.h>
                   1198: #include <math.h>
                   1199: char buf[1024], buf2[1024];
                   1200: double t;
                   1201: while(gets(buf) != NULL) {
                   1202:   sprintf(buf2,
                   1203:    "printf(|sp(\)"%%g|sp(\)|sp(\)n|sp(\)",t=(double)(%s));",
                   1204:    buf);
                   1205:     cin_eval(buf2);
                   1206: }'; cat ) | cin -i
                   1207: |end(computeroutput)
                   1208: |blank_space(-1)
                   1209: 
                   1210: |section(Acknowledgements)
                   1211: 
                   1212: We thank Brian Kernighan
                   1213: for permission to draw inspiration and borrow phrases from his editor tutorial.
                   1214: We also thank
                   1215: Sumit Bandyopadhyay,
                   1216: Bill Carpenter,
                   1217: Paul De Bra,
                   1218: Alan Hastings,
                   1219: Jonathan Helfman,
                   1220: Andrew Hume,
                   1221: Leonard Kasday,
                   1222: Brian Kernighan,
                   1223: Tom Kirk,
                   1224: David Korn,
                   1225: Lisa Kowalski,
                   1226: Richard Maus,
                   1227: Lawrence Mayka,
                   1228: Doug McIlroy,
                   1229: Marcel Meth,
                   1230: Eric Muehrcke,
                   1231: Jishnu Mukerji,
                   1232: Rob Murray,
                   1233: Sharon Peeters,
                   1234: Mike Riley,
                   1235: Larry Satz,
                   1236: Judy Schmidt,
                   1237: Timothy Schroeder,
                   1238: Jonathan Shapiro,
                   1239: Joe Steffen,
                   1240: Andy Tripp,
                   1241: Tom Walsh,
                   1242: William Wetzel,
                   1243: and
                   1244: Myron Wish
                   1245: for useful comments on previous versions of this paper.
                   1246: 
                   1247: |comment<
                   1248: |style(one_column)
                   1249: 
                   1250: |signature(MH-11229-TJK/HHG/JJP-tjk/hhg/jjp)
                   1251: >
                   1252: 
                   1253: |comment<
                   1254: |notation(Att.
                   1255: References)
                   1256: 
                   1257: |other
                   1258: >
                   1259: 
                   1260: |reference_placement
                   1261: 
                   1262: |keywords(Rapid Prototyping,
                   1263: Incremental Update,
                   1264: C Programming)
                   1265: 
                   1266: |comment<
                   1267: |mercury(cmp, elc)
                   1268: 
                   1269: |att(is_release yes)
                   1270: 
                   1271: |distribute_complete_memo(Executive Directors 112
                   1272: Directors 112
                   1273: Department Heads 1122
                   1274: Sumit Bandyopadhyay
                   1275: Bill Carpenter
                   1276: Paul De Bra
                   1277: Alan Hastings
                   1278: Jonathan Helfman
                   1279: Yean-Ming Huang
                   1280: Andrew Hume
                   1281: Leonard Kasday
                   1282: Brian Kernighan
                   1283: Tom Kirk
                   1284: David Korn
                   1285: Lisa Kowalski
                   1286: Richard Maus
                   1287: Lawrence Mayka
                   1288: Doug McIlroy
                   1289: Marcel Meth
                   1290: Eric Muerhcke
                   1291: Jishnu Mukerji
                   1292: Rob Murray
                   1293: Sharon Peeters
                   1294: Mike Riley
                   1295: Larry Satz
                   1296: Judy Schmidt
                   1297: Timothy Schroeder
                   1298: Jonathan Shapiro
                   1299: Joe Steffen
                   1300: Andy Tripp
                   1301: Tom Walsh
                   1302: William Wetzel)
                   1303: 
                   1304: |distribute_cover_sheet(A. A. Penzias
                   1305: 1122 MTS
                   1306: Miguel Abdo
                   1307: Tom Beattie
                   1308: Jim Burnash
                   1309: Tom Cargill
                   1310: John Carter
                   1311: Craig Cleaveland
                   1312: Don deCourcelle
                   1313: Helen Diamantidis
                   1314: Laura Eaves
                   1315: Faiq Fazal
                   1316: Tom Foregger
                   1317: Carol Franklin
                   1318: Narain Gehani
                   1319: Richard Greer
                   1320: John Gregg
                   1321: Jim Grenier
                   1322: Inars Gruntals
                   1323: Roy Harkness
                   1324: Kurt Haserodt
                   1325: Alan Hewett
                   1326: Viet Hoang
                   1327: James Holmes
                   1328: Mike Hudson
                   1329: Douglas Johnston
                   1330: Jon Kaplowitz
                   1331: Kevin Kinnear
                   1332: Peter Kirslis
                   1333: Balachander Krishnamurthy
                   1334: Ajoy Kumar
                   1335: David Lubinsky
                   1336: Robert Lyons
                   1337: John Malleo-Roach
                   1338: Pat McGowan
                   1339: Al McPherson
                   1340: Douglas Miller
                   1341: Datta Miruke
                   1342: John Mocenigo
                   1343: Dave Neal
                   1344: Eric Olson
                   1345: Joseph Patterson
                   1346: Virginia Piccininni
                   1347: Thomas Pisciotta
                   1348: David Potter
                   1349: Demetri Prountzos
                   1350: Benjamin Reytblat
                   1351: Ernie Rice
                   1352: James Rowland
                   1353: Ed Schan
                   1354: William Schell
                   1355: Carl Seaquist
                   1356: Steve Shepherd
                   1357: John Sherman
                   1358: Tyrone Shiu
                   1359: Les Shupe
                   1360: David Smull
                   1361: G. Mark Stewart
                   1362: Art Storm
                   1363: Rich Struse
                   1364: Mark Swartz
                   1365: Rick Thomas
                   1366: Tim Thompson
                   1367: Peter Ting
                   1368: Gregg Vesonder
                   1369: Yu-Lien Yen
                   1370: John Young
                   1371: Avi Zahavi)
                   1372: 
                   1373: |add_totals(other 4)
                   1374: 
                   1375: |cover_sheet
                   1376: >

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.