Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

cq.c

Go to the documentation of this file.
00001    struct defs {
00002      int cbits;          /* No. of bits per char           */
00003      int ibits;          /*                 int            */
00004      int sbits;          /*                 short          */
00005      int lbits;          /*                 long           */
00006      int ubits;          /*                 unsigned       */
00007      int fbits;          /*                 float          */
00008      int dbits;          /*                 double         */
00009      float fprec;        /* Smallest number that can be    */
00010      float dprec;        /* significantly added to 1.      */
00011      int flgs;           /* Print return codes, by section */
00012      int flgm;           /* Announce machine dependencies  */
00013      int flgd;           /* give explicit diagnostics      */
00014      int flgl;           /* Report local return codes.     */
00015      int rrc;            /* recent return code             */
00016      int crc;            /* Cumulative return code         */
00017      char rfs[8];        /* Return from section            */
00018    };
00019 main(n,args)               /* C REFERENCE MANUAL         */
00020 int n;
00021 char **args;
00022 {
00023 
00024 /*   This program performs a series of tests on a C compiler,
00025 based on information in the
00026 
00027              C REFERENCE MANUAL
00028 
00029 which appears as Appendix A to the book "The C Programming
00030 Language" by Brian W. Kernighan and Dennis M. Ritchie
00031 (Prentice-Hall, 1978, $10.95). This Appendix is hereafter
00032 referred to as "the Manual".
00033 
00034      The rules followed in writing this program are:
00035 
00036      1. The entire program is written in legal C, according
00037      to the Manual. It should compile with no error messages,
00038      although some warning messages may be produced by some
00039      compilers. Failure to compile should be interpreted as
00040      a compiler error.
00041 
00042      2. The program is clean, in that it does not make use
00043      of any features of the operating system on which it runs,
00044      with the sole exceptions of the printf() function, and an
00045      internal "options" routine, which is easily excised.
00046 
00047      3. No global variables are used, except for the spec-
00048      ific purpose of testing the global variable facility.
00049 
00050      The program is divided into modules having names of the
00051 form snnn... These modules correspond to those sections of the
00052 Manual, as identified by boldface type headings, in which
00053 there is something to test. For example, s241() corresponds
00054 to section 2.4.1 of the Manual (Integer constants) and tests
00055 the facilities described therein. The module numbering
00056 scheme is ambiguous, especially when it names modules
00057 referring to more than one section; module s7813, for ex-
00058 ample, deals with sections 7.8 through 7.13. Nonetheless,
00059 it is surprisingly easy to find a section in the Manual
00060 corresponding to a section of code, and vice versa.
00061 
00062      Note also that there seem to be "holes" in the program,
00063 at least from the point of view that there exist sections in the
00064 Manual for which there is no corresponding code. Such holes
00065 arise from three causes: (a) there is nothing in that partic-
00066 ular section to test, (b) everything in that section is tested
00067 elsewhere, and (c) it was deemed advisable not to check cer-
00068 tain features like preprocessor or listing control features.
00069 
00070      Modules are called by a main program main(). The mod-
00071 ules that are called, and the sequence in which they are 
00072 called, are determined by two lists in main(), in which the
00073 module names appear. The first list (an extern statement)
00074 declares the module names to be external. The second (a stat-
00075 ic int statement) names the modules and defines the sequence
00076 in which they are called. There is no need for these lists
00077 to be in the same order, but it is probably a good idea to keep
00078 them that way in the interest of clarity. Since there are no
00079 cross-linkages between modules, new modules may be added,
00080 or old ones deleted, simply by editing the lists, with one
00081 exception: section s26, which pokes around at the hardware
00082 trying to figure out the characteristics of the machine that
00083 it is running on, saves information that is subsequently
00084 used by sections s626, s72, and s757. If this program is
00085 to be broken up into smallish pieces, say for running on
00086 a microcomputer, take care to see that s26 is called before
00087 calling any of the latter three sections.  The size
00088 of the lists, i.e., the number of modules to be called, is
00089 not explicitly specified as a program parameter, but is
00090 determined dynamically using the sizeof operator.
00091 
00092      Communication between the main program and the modules
00093 takes place in two ways. In all cases, a pointer to a structure
00094 is passed to the called module. The structure contains flags
00095 that will determine the type of information to be published
00096 by the module, and fields that may be written in by the
00097 module. The former include "flgm" and "flgd", which, if set
00098 to a nonzero value, specify that machine dependencies are to
00099 be announced or that error messages are to be printed, re-
00100 spectively. The called module's name, and the hardware char-
00101 acteristics probed in s26() comprise the latter.
00102 
00103 
00104      Also, in all cases, a return code is returned by the called
00105 module. A return code of zero indicates that all has gone well;
00106 nonzero indicates otherwise. Since more than one type of error
00107 may be detected by a module, the return code is a composite
00108 of error indicators, which, individually, are given as numbers
00109 that are powers of two. Thus, a return code of 10 indicates
00110 that two specific errors, 8 and 2, were detected. Whether or
00111 not the codes returned by the modules are printed by the main
00112 program is determined by setting "flgs" to 1 (resp. 0).
00113 
00114      The entire logic of the main program is contained in the
00115 half-dozen or so lines at the end. The somewhat cryptic 
00116 statement:
00117 
00118            d0.rrc = (*sec[j])(pd0);
00119 
00120 in the for loop calls the modules. The rest of the code is
00121 reasonably straightforward.
00122 
00123      Finally, in each of the modules, there is the following
00124 prologue:
00125 
00126            snnn(pd0)
00127            struct defs *pd0;
00128            {
00129               static char snnner[] = "snnn,er%d\n";
00130               static char qsnnn[8] = "snnn   ";
00131               char *ps, *pt;
00132               int rc;
00133 
00134               rc = 0;
00135               ps = qsnnn;
00136               pt = pd0->rfs;
00137               while(*pt++ = *ps++);
00138 
00139 used for housekeeping, handshaking and module initialization.
00140 
00141                                                            */
00142    extern
00143      s22(),
00144      s241(),
00145      s243(),
00146      s244(),
00147      s25(),
00148      s26(),
00149      s4(),
00150      s61(),
00151      s626(),
00152      s71(),
00153      s72(),
00154      s757(),
00155      s7813(),
00156      s714(),
00157      s715(),
00158      s81(),
00159      s84(),
00160      s85(),
00161      s86(),
00162      s88(),
00163      s9()
00164    ;
00165 
00166    int j;
00167    static int (*sec[])() = {
00168      s22,
00169      s241,
00170      s243,
00171      s244,
00172      s25,
00173      s26,
00174      s4,
00175      s61,
00176      s626,
00177      s71,
00178      s72,
00179      s757,
00180      s7813,
00181      s714,
00182      s715,
00183      s81,
00184      s84,
00185      s85,
00186      s86,
00187      s88,
00188      s9
00189    };
00190 
00191    static struct defs d0, *pd0;
00192     
00193      d0.flgs = 1;          /* These flags dictate            */
00194      d0.flgm = 1;          /*     the verbosity of           */
00195      d0.flgd = 1;          /*         the program.           */
00196      d0.flgl = 1;
00197 
00198    pd0 = &d0;
00199 
00200    for (j=0; j<sizeof(sec) / sizeof(sec[0]); j++) {
00201      d0.rrc = (*sec[j])(pd0);
00202      d0.crc = d0.crc+d0.rrc;
00203      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
00204    }
00205   
00206    if(d0.crc == 0) printf("\nNo errors detected.\n");
00207    else printf("\nFailed.\n");
00208    return 0;
00209 }
00210 s22(pd0)                 /* 2.2 Identifiers (Names)      */
00211 struct defs *pd0;
00212 {
00213    int a234, a;
00214    int _, _234, A, rc;
00215 
00216    static char s22er[] = "s22,er%d\n";
00217    static char qs22[8] = "s22    ";
00218 
00219    char *ps, *pt;
00220                          /* Initialize                      */
00221 
00222    rc = 0;
00223    ps = qs22;
00224    pt = pd0 -> rfs;
00225    while (*pt++ = *ps++);
00226 
00227      /* An identifier is a sequence of letters and digits;
00228         the first character must be a letter. The under-
00229         score _ counts as a letter.                        */
00230 
00231    a=1;
00232    _=2;
00233    _234=3;
00234    a234=4;
00235    if(a+_+_234+a234 != 10) {
00236      rc = rc+1;
00237      if(pd0->flgd != 0) printf(s22er,1);
00238    }
00239 
00240    /* Upper and lower case letters are different.     */
00241 
00242    A = 2;
00243    if (A == a) {
00244      rc = rc+4;
00245      if (pd0->flgd != 0) printf(s22er,4);
00246    }
00247 
00248    return(rc);
00249 }
00250 s241(pd0)                   /* 2.4.1 Integer constants
00251                                2.4.2 Explicit long constants  */
00252 struct defs *pd0;
00253 {
00254    long pow2();
00255    static char s241er[] = "s241,er%d\n";
00256    static char qs241[8] = "s241   ";
00257    char *ps, *pt;
00258    int rc, j, lrc;
00259    static long g[39] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00260                         0,6,0,8,0,12,0,16,0,18,0,20,0,24,
00261                         0,28,0,30,0,32,0,36};
00262    long d[39], o[39], x[39];
00263 
00264    rc = 0;
00265    lrc = 0;
00266    ps = qs241;
00267    pt = pd0 -> rfs;
00268    while (*pt++ = *ps++);
00269 
00270      /* An integer constant consisting of a sequence of digits is
00271         taken to be octal if it begins with 0 (digit zero), decimal
00272         otherwise.                                            */
00273 
00274    if (   8 !=  010
00275      ||  16 !=  020
00276      ||  24 !=  030
00277      ||  32 !=  040
00278      ||  40 !=  050
00279      ||  48 !=  060
00280      ||  56 !=  070
00281      ||  64 != 0100
00282      ||  72 != 0110
00283      ||  80 != 0120
00284      ||   9 != 0011
00285      ||  17 != 0021
00286      ||  25 != 0031
00287      ||  33 != 0041
00288      ||  41 != 0051
00289      ||  49 != 0061
00290      ||  57 != 0071
00291      ||  65 != 0101
00292      ||  73 != 0111
00293      ||  81 != 0121 ){
00294 
00295      rc = rc+1;
00296      if( pd0->flgd != 0 ) printf(s241er,1);
00297    }
00298 
00299      /* A sequence of digits preceded by 0x or 0X (digit zero)
00300         is taken to be a hexadecimal integer. The hexadecimal
00301         digits include a or A through f or F with values 10
00302         through 15.     */
00303 
00304    if ( 0x00abcdef != 0xabcdef
00305      || 0xabcdef != 0Xabcdef || 0Xabcdef != 0XAbcdef
00306      || 0XAbcdef != 0XABcdef || 0XABcdef != 0XABCdef
00307      || 0XABCdef != 0XABCDef || 0XABCDef != 0XABCDEf
00308      || 0XABCDEf != 0XABCDEF || 0xABCDEF != 11259375 ){
00309 
00310      rc = rc+2;
00311      if( pd0->flgd != 0 ) printf(s241er,2);
00312    }
00313 
00314      /* A decimal constant whose value exceeds the largest signed
00315         machine integer is taken to be long; an octal or hex con-
00316         stant which exceeds the largest unsigned machine integer
00317         is likewise taken to be long.     */
00318 
00319    if ( sizeof 010000000000 != sizeof(long)      /* 2**30 */
00320      || sizeof 1073741824   != sizeof(long)      /* ditto */
00321      || sizeof 0x40000000   != sizeof(long) ){   /*   "   */
00322 
00323      rc = rc+4;
00324      if( pd0->flgd != 0 ) printf(s241er,4);
00325    }
00326 
00327      /* A decimal, octal, or hexadecimal constant immediately followed
00328         by l (letter ell) or L is a long constant.    */
00329 
00330    if ( sizeof   67l != sizeof(long)
00331      || sizeof   67L != sizeof(long)
00332      || sizeof  067l != sizeof(long)
00333      || sizeof  067L != sizeof(long)
00334      || sizeof 0X67l != sizeof(long)
00335      || sizeof 0x67L != sizeof(long) ){
00336 
00337      rc = rc+8;
00338      if( pd0 -> flgd != 0 ) printf(s241er,8);
00339    }
00340 
00341      /* Finally, we test to see that decimal (d), octal (o),
00342         and hexadecimal (x) constants representing the same values
00343         agree among themselves, and with computed values, at spec-
00344         ified points over an appropriate range. The points select-
00345         ed here are those with the greatest potential for caus-
00346         ing trouble, i.e., zero, 1-16, and values of 2**n and
00347         2**n - 1 where n is some multiple of 4 or 6. Unfortunately,
00348         just what happens when a value is too big to fit in a
00349         long is undefined; however, it would be nice if what
00350         happened were at least consistent...      */
00351 
00352    for ( j=0; j<17; j++ ) g[j] = j;
00353    for ( j=18; j<39; ) {
00354      g[j] = pow2(g[j]);
00355      g[j-1] = g[j] - 1;
00356      j = j+2;
00357    }
00358 
00359    d[0] = 0;                o[0] = 00;               x[0] = 0x0;
00360    d[1] = 1;                o[1] = 01;               x[1] = 0x1;
00361    d[2] = 2;                o[2] = 02;               x[2] = 0x2;
00362    d[3] = 3;                o[3] = 03;               x[3] = 0x3;
00363    d[4] = 4;                o[4] = 04;               x[4] = 0x4;
00364    d[5] = 5;                o[5] = 05;               x[5] = 0x5;
00365    d[6] = 6;                o[6] = 06;               x[6] = 0x6;
00366    d[7] = 7;                o[7] = 07;               x[7] = 0x7;
00367    d[8] = 8;                o[8] = 010;              x[8] = 0x8;
00368    d[9] = 9;                o[9] = 011;              x[9] = 0x9;
00369    d[10] = 10;              o[10] = 012;             x[10] = 0xa;
00370    d[11] = 11;              o[11] = 013;             x[11] = 0xb;
00371    d[12] = 12;              o[12] = 014;             x[12] = 0xc;
00372    d[13] = 13;              o[13] = 015;             x[13] = 0xd;
00373    d[14] = 14;              o[14] = 016;             x[14] = 0xe;
00374    d[15] = 15;              o[15] = 017;             x[15] = 0xf;
00375    d[16] = 16;              o[16] = 020;             x[16] = 0x10;
00376    d[17] = 63;              o[17] = 077;             x[17] = 0x3f;
00377    d[18] = 64;              o[18] = 0100;            x[18] = 0x40;
00378    d[19] = 255;             o[19] = 0377;            x[19] = 0xff;
00379    d[20] = 256;             o[20] = 0400;            x[20] = 0x100;
00380    d[21] = 4095;            o[21] = 07777;           x[21] = 0xfff;
00381    d[22] = 4096;            o[22] = 010000;          x[22] = 0x1000;
00382    d[23] = 65535;           o[23] = 0177777;         x[23] = 0xffff;
00383    d[24] = 65536;           o[24] = 0200000;         x[24] = 0x10000;
00384    d[25] = 262143;          o[25] = 0777777;         x[25] = 0x3ffff;
00385    d[26] = 262144;          o[26] = 01000000;        x[26] = 0x40000;
00386    d[27] = 1048575;         o[27] = 03777777;        x[27] = 0xfffff;
00387    d[28] = 1048576;         o[28] = 04000000;        x[28] = 0x100000;
00388    d[29] = 16777215;        o[29] = 077777777;       x[29] = 0xffffff;
00389    d[30] = 16777216;        o[30] = 0100000000;      x[30] = 0x1000000;
00390    d[31] = 268435455;       o[31] = 01777777777;     x[31] = 0xfffffff;
00391    d[32] = 268435456;       o[32] = 02000000000;     x[32] = 0x10000000;
00392    d[33] = 1073741823;      o[33] = 07777777777;     x[33] = 0x3fffffff;
00393    d[34] = 1073741824;      o[34] = 010000000000;    x[34] = 0x40000000;
00394    d[35] = 4294967295;      o[35] = 037777777777;    x[35] = 0xffffffff;
00395    d[36] = 4294967296;      o[36] = 040000000000;    x[36] = 0x100000000;
00396    d[37] = 68719476735;     o[37] = 0777777777777;   x[37] = 0xfffffffff;
00397    d[38] = 68719476736;     o[38] = 01000000000000;  x[38] = 0x1000000000;
00398 
00399    /* WHEW! */
00400 
00401    for (j=0; j<39; j++){
00402      if ( g[j] != d[j]
00403        || d[j] != o[j]
00404        || o[j] != x[j]) {
00405 
00406        if( pd0 -> flgm != 0 ) {
00407 /*       printf(s241er,16);          save in case opinions change...     */
00408          printf("Decimal and octal/hex constants sometimes give\n");
00409          printf("   different results when assigned to longs.\n");
00410        }
00411 /*     lrc = 1;   save...   */
00412      }
00413    }
00414 
00415    if (lrc != 0) rc =16;
00416 
00417    return rc;
00418 }
00419 
00420 long pow2(n)        /* Calculate 2**n by multiplying, not shifting  */
00421 long n;
00422 {
00423    long s;
00424    s = 1;
00425    while(n--) s = s*2;
00426    return s;
00427 }
00428 s243(pd0)                   /*  2.4.3 Character constants  */
00429 struct defs *pd0;
00430 {
00431    static char s243er[] = "s243,er%d\n";
00432    static char qs243[8] = "s243   ";
00433    char *ps, *pt;
00434    int rc;
00435    char chars[256];
00436 
00437    rc = 0;
00438    ps = qs243;
00439    pt = pd0->rfs;
00440    while(*pt++ = *ps++);
00441 
00442      /* One of the problems that arises when testing character constants
00443         is that of definition: What, exactly, is the character set?
00444         In order to guarantee a certain amount of machine independence,
00445         the character set we will use here is the set of characters writ-
00446         able as escape sequences in C, plus those characters used in writ-
00447         ing C programs, i.e.,
00448 
00449         letters:
00450                    ABCDEFGHIJKLMNOPQRSTUVWXYZ      26
00451                    abcdefghijklmnopqrstuvwxyz      26
00452         numbers:
00453                    0123456789                      10
00454         special characters:
00455                    ~!"#%&()_=-^|{}[]+;*:<>,.?/     27
00456         extra special characters:
00457                    newline           \n       
00458                    horizontal tab    \t
00459                    backspace         \b
00460                    carriage return   \r
00461                    form feed         \f
00462                    backslash         \\
00463                    single quote      \'             7
00464         blank & NUL                                 2
00465                                                   ---
00466                                                    98
00467 
00468         Any specific implementation of C may of course support additional
00469         characters.                                       */
00470 
00471         /* Since the value of a character constant is the numerical value
00472            of the character in the machine's character set, there should
00473            be a one-to-one correspondence between characters and values. */
00474 
00475    zerofill(chars);
00476 
00477    chars['a'] = 1;   chars['A'] = 1;   chars['~'] = 1;   chars['0'] = 1;
00478    chars['b'] = 1;   chars['B'] = 1;   chars['!'] = 1;   chars['1'] = 1;
00479    chars['c'] = 1;   chars['C'] = 1;   chars['"'] = 1;   chars['2'] = 1;
00480    chars['d'] = 1;   chars['D'] = 1;   chars['#'] = 1;   chars['3'] = 1;
00481    chars['e'] = 1;   chars['E'] = 1;   chars['%'] = 1;   chars['4'] = 1;
00482    chars['f'] = 1;   chars['F'] = 1;   chars['&'] = 1;   chars['5'] = 1;
00483    chars['g'] = 1;   chars['G'] = 1;   chars['('] = 1;   chars['6'] = 1;
00484    chars['h'] = 1;   chars['H'] = 1;   chars[')'] = 1;   chars['7'] = 1;
00485    chars['i'] = 1;   chars['I'] = 1;   chars['_'] = 1;   chars['8'] = 1;
00486    chars['j'] = 1;   chars['J'] = 1;   chars['='] = 1;   chars['9'] = 1;
00487    chars['k'] = 1;   chars['K'] = 1;   chars['-'] = 1;
00488    chars['l'] = 1;   chars['L'] = 1;   chars['^'] = 1;
00489    chars['m'] = 1;   chars['M'] = 1;   chars['|'] = 1;   chars['\n'] = 1;
00490    chars['n'] = 1;   chars['N'] = 1;                     chars['\t'] = 1;
00491    chars['o'] = 1;   chars['O'] = 1;   chars['{'] = 1;   chars['\b'] = 1;
00492    chars['p'] = 1;   chars['P'] = 1;   chars['}'] = 1;   chars['\r'] = 1;
00493    chars['q'] = 1;   chars['Q'] = 1;   chars['['] = 1;   chars['\f'] = 1;
00494    chars['r'] = 1;   chars['R'] = 1;   chars[']'] = 1;
00495    chars['s'] = 1;   chars['S'] = 1;   chars['+'] = 1;   chars['\\'] = 1;
00496    chars['t'] = 1;   chars['T'] = 1;   chars[';'] = 1;   chars['\''] = 1;
00497    chars['u'] = 1;   chars['U'] = 1;   chars['*'] = 1;  
00498    chars['v'] = 1;   chars['V'] = 1;   chars[':'] = 1;   chars['\0'] = 1;
00499    chars['w'] = 1;   chars['W'] = 1;   chars['<'] = 1;   chars[' '] = 1;
00500    chars['x'] = 1;   chars['X'] = 1;   chars['>'] = 1;
00501    chars['y'] = 1;   chars['Y'] = 1;   chars[','] = 1;
00502    chars['z'] = 1;   chars['Z'] = 1;   chars['.'] = 1;
00503                                        chars['?'] = 1;
00504                                        chars['/'] = 1;
00505 
00506    if(sumof(chars) != 98){
00507      rc = rc+1;
00508      if(pd0->flgd != 0) printf(s243er,1);
00509    }
00510 
00511    /* Finally, the escape \ddd consists of the backslash followed
00512       by 1, 2, or 3 octal digits which are taken to specify  the
00513       desired character.                           */
00514 
00515    if( '\0'    !=   0 || '\01'   !=   1 || '\02'   !=   2
00516     || '\03'   !=   3 || '\04'   !=   4 || '\05'   !=   5
00517     || '\06'   !=   6 || '\07'   !=   7 || '\10'   !=   8
00518     || '\17'   !=  15 || '\20'   !=  16 || '\77'   !=  63
00519     || '\100'  !=  64 || '\177'  != 127                 ){
00520    
00521      rc = rc+8;
00522      if(pd0->flgd != 0) printf(s243er,8);
00523    }
00524 
00525    return rc;
00526 }
00527 zerofill(x)
00528 char *x;
00529 {
00530    int j;
00531 
00532    for (j=0; j<256; j++) *x++ = 0;
00533 }
00534 sumof(x)
00535 char *x;
00536 {
00537    char *p;
00538    int total, j;
00539 
00540    p = x;
00541    total = 0;
00542 
00543    for(j=0; j<256; j++) total = total+ *p++;
00544    return total;
00545 }
00546 s244(pd0)
00547 struct defs *pd0;
00548 {
00549    double a[8];
00550    int rc, lrc, j;
00551    static char s244er[] = "s244,er%d\n";
00552    static char qs244[8] = "s244   ";
00553    char *ps, *pt;
00554 
00555    ps = qs244;
00556    pt = pd0->rfs;
00557    while(*pt++ = *ps++);
00558    rc = 0;
00559    lrc = 0;
00560 
00561    /* Unfortunately, there's not a lot we can do with floating constants.
00562       We can check to see that the various representations can be com-
00563       piled, that the conversion is such that they yield the same hard-
00564       ware representations in all cases, and that all representations
00565       thus checked are double precision.              */
00566 
00567    a[0] = .1250E+04;
00568    a[1] = 1.250E3;
00569    a[2] = 12.50E02;
00570    a[3] = 125.0e+1;
00571    a[4] = 1250e00;
00572    a[5] = 12500.e-01;
00573    a[6] = 125000e-2;
00574    a[7] = 1250.;
00575 
00576    lrc = 0;
00577    for (j=0; j<7; j++) if(a[j] != a[j+1]) lrc = 1;
00578 
00579    if(lrc != 0) {
00580      if(pd0->flgd != 0) printf(s244er,1);
00581      rc = rc+1;
00582    }
00583 
00584    if ( (sizeof .1250E+04 ) != sizeof(double)
00585      || (sizeof 1.250E3   ) != sizeof(double)
00586      || (sizeof 12.50E02  ) != sizeof(double)
00587      || (sizeof 1.250e+1  ) != sizeof(double)
00588      || (sizeof 1250e00   ) != sizeof(double)
00589      || (sizeof 12500.e-01) != sizeof(double)
00590      || (sizeof 125000e-2 ) != sizeof(double)
00591      || (sizeof 1250.     ) != sizeof(double)){
00592      
00593      if(pd0->flgd != 0) printf(s244er,2);
00594      rc = rc+2;
00595    }
00596 
00597    return rc;
00598 }
00599 s25(pd0)
00600 struct defs *pd0;
00601 {
00602    char *s, *s2;
00603    int rc, lrc, j;
00604    static char s25er[] = "s25,er%d\n";
00605    static char qs25[8] = "s25    ";
00606    char *ps, *pt;
00607 
00608    ps = qs25;
00609    pt = pd0->rfs;
00610    while(*pt++ = *ps++);
00611    rc = 0;
00612 
00613    /* A string is a sequence of characters surrounded by double
00614       quotes, as in "...".                         */
00615 
00616    s = "...";
00617 
00618    /* A string has type "array of characters" and storage class
00619       static and is initialized with the given characters.  */
00620 
00621    if ( s[0] != s[1] || s[1] != s[2]
00622      || s[2] != '.' ) {
00623 
00624     rc = rc+1;
00625      if(pd0->flgd != 0) printf(s25er,1);
00626    }
00627 
00628    /* The compiler places a null byte \0 at the end of each string
00629       so the program which scans the string can find its end.   */
00630 
00631    if( s[3] != '\0' ){
00632      rc = rc+4;
00633      if(pd0->flgd != 0) printf(s25er,4);
00634    }
00635 
00636    /* In a string, the double quote character " must be preceded
00637       by a \.                                               */
00638 
00639     if( ".\"."[1] != '"' ){
00640     rc = rc+8;
00641      if(pd0->flgd != 0) printf(s25er,8);
00642    }
00643 
00644    /* In addition, the same escapes described for character constants
00645       may be used.                                            */
00646 
00647    s = "\n\t\b\r\f\\\'";
00648 
00649    if( s[0] != '\n'
00650     || s[1] != '\t'
00651     || s[2] != '\b'
00652     || s[3] != '\r'
00653     || s[4] != '\f'
00654     || s[5] != '\\'
00655     || s[6] != '\'' ){
00656 
00657      rc = rc+16;
00658      if( pd0->flgd != 0) printf(s25er,16);
00659    }
00660 
00661    /* Finally, a \ and an immediately following newline are ignored */
00662 
00663    s2 = "queep!";
00664    s = "queep!";
00665 
00666    lrc = 0;
00667    for (j=0; j<sizeof "queep!"; j++) if(s[j] != s2[j]) lrc = 1;
00668    if (lrc != 0){
00669      rc = rc+32;
00670      if(pd0->flgd != 0) printf(s25er,32);
00671    }
00672    return rc;
00673 }
00674 s26(pd0)                  /*  2.6  Hardware Characteristics     */
00675 struct defs *pd0;
00676 {
00677    static char qs26[8] = "s26    ";
00678    char *ps, *pt;
00679    char c0, c1;
00680    float temp, one, delta;
00681    double tempd, oned;
00682    static char s[] = "%3d bits in %ss.\n";
00683    static char s2[] = "%e is the least number that can be added to 1. (%s).\n";
00684 
00685    ps = qs26;
00686    pt = pd0->rfs;
00687 
00688    while(*pt++ = *ps++);
00689 
00690           /* Here, we shake the machinery a little to see what falls
00691              out.  First, we find out how many bits are in a char.  */
00692 
00693    pd0->cbits = 0;
00694    c0 = 0;
00695    c1 = 1;
00696 
00697    while(c0 != c1) {
00698      c1 = c1<<1;
00699      pd0->cbits = pd0->cbits+1;
00700    }
00701           /* That information lets us determine the size of everything else. */
00702 
00703    pd0->ibits = pd0->cbits * sizeof(int);
00704    pd0->sbits = pd0->cbits * sizeof(short);
00705    pd0->lbits = pd0->cbits * sizeof(long);
00706    pd0->ubits = pd0->cbits * sizeof(unsigned);
00707    pd0->fbits = pd0->cbits * sizeof(float);
00708    pd0->dbits = pd0->cbits * sizeof(double);
00709 
00710           /* We have now almost reconstructed the table in section 2.6, the
00711              exception being the range of the floating point hardware.
00712              Now there are just so many ways to conjure up a floating point
00713              representation system that it's damned near impossible to guess
00714              what's going on by writing a program to interpret bit patterns.
00715              Further, the information isn't all that useful, if we consider
00716              the fact that machines that won't handle numbers between 10**30
00717              and 10**-30 are very hard to find, and that people playing with
00718              numbers outside that range have a lot more to worry about than
00719              just the capacity of the characteristic.
00720 
00721              A much more useful measure is the precision, which can be ex-
00722              pressed in terms of the smallest number that can be added to
00723              1. without loss of significance. We calculate that here, for
00724              float and double.                       */
00725 
00726    one = 1.;
00727    delta = 1.;
00728    temp = 0.;
00729    while(temp != one) {
00730      temp = one+delta;
00731      delta = delta/2.;
00732    }
00733    pd0->fprec = delta * 4.;
00734    oned = 1.;
00735    delta = 1.;
00736    tempd = 0.;
00737    while(tempd != oned) {
00738      tempd = oned+delta;
00739      delta = delta/2.;
00740    }
00741    pd0->dprec = delta * 4.;
00742 
00743           /* Now, if anyone's interested, we publish the results.       */
00744 
00745    if(pd0->flgm != 0) {
00746      printf(s,pd0->cbits,"char");
00747      printf(s,pd0->ibits,"int");
00748      printf(s,pd0->sbits,"short");
00749      printf(s,pd0->lbits,"long");
00750      printf(s,pd0->ubits,"unsigned");
00751      printf(s,pd0->fbits,"float");
00752      printf(s,pd0->dbits,"double");
00753      printf(s2,pd0->fprec,"float");
00754      printf(s2,pd0->dprec,"double");
00755    }
00756           /* Since we are only exploring and perhaps reporting, but not 
00757              testing any features, we cannot return an error code.  */
00758 
00759    return 0;
00760 }
00761 int extvar;
00762 s4(pd0)                    /* 4. What's in a name?             */
00763 struct defs *pd0;
00764 {
00765    static char s4er[] = "s4,er%d\n";
00766    static char qs4[8] = "s4     ";
00767    char *ps, *pt;
00768    int j, rc;
00769 
00770    short sint;             /* short integer, for size test      */
00771    int pint;               /* plain                             */
00772    long lint;              /* long                              */
00773    unsigned target;
00774    unsigned int mask;
00775 
00776    rc = 0;
00777    ps = qs4;
00778    pt = pd0->rfs;
00779 
00780    while(*pt++ = *ps++);
00781 
00782 /*   There are four declarable storage classes: automatic,
00783 static, external, and register. Automatic variables have
00784 been dealt with extensively thus far, and will not be specif-
00785 ically treated in this section. Register variables are treated
00786 in section s81.
00787 
00788      Static variables are local to a block, but retain their
00789 values upon reentry to a block, even after control has left
00790 the block.                                                     */
00791 
00792    for (j=0; j<3; j++)
00793      if(svtest(j) != zero()){
00794        rc = 1;
00795        if(pd0->flgd != 0) printf(s4er,1);
00796      }
00797    ;
00798 
00799 /*   External variables exist and retain their values throughout
00800 the execution of the entire program, and may be used for comm-
00801 unication between functions, even separately compiled functions.
00802                                                                 */
00803 
00804    setev();
00805    if(testev() != 0){
00806      rc=rc+2;
00807      if(pd0->flgd != 0) printf(s4er,2);
00808    }
00809 /*   
00810      Characters have been tested elsewhere (in s243).
00811 
00812      Up to three sizes of integer, declared short int, int, and
00813 long int, are available. Longer integers provide no less storage
00814 than shorter ones, but implementation may make either short
00815 integers, or long integers, or both, equivalent to plain
00816 integers.
00817                                                                 */
00818 
00819    if(sizeof lint < sizeof pint || sizeof pint < sizeof sint){
00820 
00821      rc = rc+4;
00822      if(pd0->flgd != 0) printf(s4er,4);
00823    }
00824 
00825 /*   Unsigned integers, declared unsigned, obey the laws of
00826 arithmetic modulo 2**n, where n is the number of bits in the
00827 implementation                                                  */
00828 
00829    target = ~0U;
00830    mask = 1;
00831  
00832    for(j=0; j<(sizeof target)*pd0->cbits; j++){
00833    
00834      mask = mask&target;
00835      target = target>>1;
00836    }
00837 
00838    if(mask != 1 || target != 0){
00839 
00840      rc = rc+8;
00841      if(pd0->flgd != 0) printf(s4er,8);
00842    }
00843 
00844    return rc;
00845 }
00846 svtest(n)
00847 int n;
00848 {
00849    static k;
00850    int rc;
00851    switch (n) {
00852 
00853      case 0: k = 1978;
00854              rc = 0;
00855              break;
00856 
00857      case 1: if(k != 1978) rc = 1;
00858              else{
00859               k = 1929;
00860               rc = 0;
00861              }
00862              break;
00863 
00864      case 2: if(k != 1929) rc = 1;
00865              else rc = 0;
00866              break;
00867    }
00868    return rc;
00869 }
00870 zero(){                 /* Returns a value of zero, possibly */
00871    static k;            /* with side effects, as it's called */
00872    int rc;              /* alternately with svtest, above,   */
00873    k = 2;               /* and has the same internal storage */
00874    rc = 0;              /* requirements.                     */
00875    return rc;
00876 }
00877 testev(){
00878    if(extvar != 1066) return 1;
00879    else return 0;
00880 }
00881 s61(pd0)          /* Characters and integers */
00882 struct defs *pd0;
00883 {
00884    static char s61er[] = "s61,er%d\n";
00885    static char qs61[8] = "s61    ";
00886    short from, shortint;
00887    long int to, longint;
00888    int rc, lrc;
00889    int j;
00890    char fromc, charint;
00891    char *wd, *pc[6];
00892    
00893    static char upper_alpha[]             = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00894    static char lower_alpha[]             = "abcdefghijklmnopqrstuvwxyz";
00895    static char numbers[]               = "0123456789";
00896    static char special_characters[]    = "~!\"#%&()_=-^|{}[]+;*:<>,.?/";
00897    static char extra_special_characters[] = "\n\t\b\r\f\\\'";
00898    static char blank_and_NUL[]            = " \0";
00899 
00900    char *ps, *pt;
00901    ps = qs61;
00902    pt = pd0->rfs;
00903    rc = 0;
00904    while (*pt++ = *ps++);
00905 
00906 /*      A character or a short integer may be used wherever
00907 an integer may be used. In all cases, the value is converted
00908 to integer. This principle is extensively used throughout this
00909 program, and will not be explicitly tested here.        */
00910 
00911 /*      Conversion of a shorter integer to a longer always
00912 involves sign extension.                                */
00913 
00914    from = -19;
00915    to = from;
00916 
00917    if(to != -19){
00918      rc = rc+1;
00919      if(pd0->flgd != 0) printf(s61er,1);
00920    }
00921 
00922 /*      It is guaranteed that a member of the standard char-
00923 acter set is nonnegative.                               */
00924 
00925    pc[0] = upper_alpha;
00926    pc[1] = lower_alpha;
00927    pc[2] = numbers;
00928    pc[3] = special_characters;
00929    pc[4] = extra_special_characters;
00930    pc[5] = blank_and_NUL;
00931 
00932    lrc = 0;
00933    for (j=0; j<6; j++)
00934      while(*pc[j]) if(*pc[j]++ < 0) lrc =1;
00935 
00936    if(lrc != 0){
00937      rc=rc+2;
00938      if(pd0->flgd != 0) printf(s61er,2);
00939    }
00940 
00941 /*      When a longer integer is converted to a shorter or
00942 to  a char, it is truncated on the left; excess bits are 
00943 simply discarded.                                       */
00944 
00945    longint = 1048579;           /* =2**20+3 */
00946    shortint = longint;
00947    charint = longint;
00948 
00949    if((shortint != longint && shortint != 3) ||
00950       (charint  != longint && charint  != 3)) {
00951      rc = rc+8;
00952      if(pd0->flgd != 0) printf(s61er,8);
00953    }
00954 
00955    return rc;
00956 }
00957 s626(pd0)          /* 6.2 Float and double                  */
00958                    /* 6.3 Floating and integral                 */
00959                    /* 6.4 Pointers and integers                 */
00960                    /* 6.5 Unsigned                              */
00961                    /* 6.6 Arithmetic conversions                */
00962 struct defs *pd0;
00963 {
00964    static char s626er[] = "s626,er%d\n";
00965    static char qs626[8] = "s626   ";
00966    int rc;
00967    char *ps, *pt;
00968    float eps, f1, f2, f3, f4, f;
00969    long lint1, lint2, l, ls;
00970    char c, t[28], t0;
00971    short s;
00972    int is, i, j;
00973    unsigned u, us;
00974    double d, ds;
00975    ps = qs626;
00976    pt = pd0->rfs;
00977    rc = 0;
00978    while (*pt++ = *ps++);
00979 
00980         /* Conversions of integral values to floating type are
00981         well-behaved.                                           */
00982 
00983    f1 = 1.;
00984    lint1 = 1.;
00985    lint2 = 1.;
00986 
00987    for(j=0;j<pd0->lbits-2;j++){
00988      f1 = f1*2;
00989      lint2 = (lint2<<1)|lint1;
00990    }
00991    f2 = lint2;
00992    f1 = (f1-f2)/f1;
00993    if(f1>2.*pd0->fprec){
00994 
00995      rc = rc+2;
00996      if(pd0->flgd != 0) printf(s626er,2);
00997    }
00998 
00999         /* Pointer-integer combinations are discussed in s74,
01000         "Additive operators". The unsigned-int combination
01001         appears below.                                          */
01002 
01003    c = 125;
01004    s = 125;
01005    i = 125;     is = 15625;
01006    u = 125;     us = 15625;
01007    l = 125;     ls = 15625;
01008    f = 125.;
01009    d = 125.;    ds = 15625.;
01010 
01011    for(j=0;j<28;j++) t[j] = 0;
01012 
01013    if(c*c != is) t[ 0] = 1;
01014    if(s*c != is) t[ 1] = 1;
01015    if(s*s != is) t[ 2] = 1;
01016    if(i*c != is) t[ 3] = 1;
01017    if(i*s != is) t[ 4] = 1;
01018    if(i*i != is) t[ 5] = 1;
01019    if(u*c != us) t[ 6] = 1;
01020    if(u*s != us) t[ 7] = 1;
01021    if(u*i != us) t[ 8] = 1;
01022    if(u*u != us) t[ 9] = 1;
01023    if(l*c != ls) t[10] = 1;
01024    if(l*s != ls) t[11] = 1;
01025    if(l*i != ls) t[12] = 1;
01026    if(l*u != us) t[13] = 1;
01027    if(l*l != ls) t[14] = 1;
01028    if(f*c != ds) t[15] = 1;
01029    if(f*s != ds) t[16] = 1;
01030    if(f*i != ds) t[17] = 1;
01031    if(f*u != ds) t[18] = 1;
01032    if(f*l != ds) t[19] = 1;
01033    if(f*f != ds) t[20] = 1;
01034    if(d*c != ds) t[21] = 1;
01035    if(d*s != ds) t[22] = 1;
01036    if(d*i != ds) t[23] = 1;
01037    if(d*u != ds) t[24] = 1;
01038    if(d*l != ds) t[25] = 1;
01039    if(d*f != ds) t[26] = 1;
01040    if(d*d != ds) t[27] = 1;
01041 
01042    t0 = 0;
01043    for(j=0; j<28; j++) t0 = t0+t[j];
01044 
01045    if(t0 != 0){
01046 
01047      rc = rc+4;
01048      if(pd0->flgd != 0){
01049 
01050        printf(s626er,4);
01051        printf("   key=");
01052        for(j=0;j<28;j++) printf("%d",t[j]);
01053        printf("\n");
01054      }
01055    }
01056 
01057         /* When an unsigned integer is converted to long,
01058            the value of the result is the same numerically
01059            as that of the unsigned integer.               */
01060 
01061    l = (unsigned)0100000;
01062    if((long)l > (unsigned)0100000){
01063 
01064       rc = rc+8;
01065       if(pd0->flgd != 0) printf(s626er,8);
01066    }
01067 
01068    return rc;
01069 }
01070 s71(pd0)          /*         7.1  Primary expressions   */
01071 struct defs *pd0;
01072 {
01073    static char s71er[] = "s71,er%d\n";
01074    static char qs71[8] = "s71    ";
01075    int rc;
01076    char *ps, *pt;
01077    static char q = 'q';
01078    int x[10], McCarthy(), clobber(), a, b, *p;
01079    ps = qs71;
01080    pt = pd0->rfs;
01081    rc = 0;
01082    while (*pt++ = *ps++);
01083 
01084 /*   Testing of expressions and operators is quite complicated,
01085      because (a) problems are apt to surface in queer combinations
01086      of operators and operands, rather than in isolation,
01087      and (b) the number of expressions needed to provoke a case
01088      of improper behaviour may be quite large. Hence, we take the
01089      following approach: for this section, and for subsequent
01090      sections through 7.15, we will check the primitive operations
01091      in isolation, thus verifying that the primitives work,
01092      after a fashion. The job of testing combinations, we will
01093      leave to a separate, machine-generated program, to be included
01094      in the C test package at some later date.
01095                                                                 */
01096 
01097 /*   A string is a primary expression. The identifier points to
01098      the first character of a string.
01099                                                                   */
01100 
01101    if(*"queep" != q){
01102      rc = rc+1;
01103      if(pd0->flgd  != 0) printf(s71er,1);
01104    }
01105 /*   A parenthesized expression is a primary expression whose
01106      type and value are the same as those of the unadorned
01107      expression.
01108                                                                 */
01109    if((2+3) != 2+3) {
01110      rc = rc+2;
01111      if(pd0->flgd != 0) printf(s71er,2);
01112    }
01113 
01114 /*   A primary expression followed by an expression in square 
01115      brackets is a primary expression. The intuitive meaning is
01116      that of a subscript. The expression E1[E2] is identical
01117      (by definition) to *((E1)+(E2)).
01118                                                                 */
01119 
01120    x[5] = 1942;
01121    if(x[5] != 1942 || x[5] != *((x)+(5))){
01122      rc = rc+4;
01123      if(pd0->flgd != 0) printf(s71er,4);
01124    }
01125 
01126 /*   If the various flavors of function calls didn't work, we
01127      would never have gotten this far; however, we do need to 
01128      show that functions can be recursive...
01129                                                                */
01130 
01131    if ( McCarthy(-5) != 91){
01132      rc = rc+8;
01133      if(pd0->flgd != 0) printf(s71er,8);
01134    }
01135 
01136 /*   and that argument passing is strictly by value.           */
01137 
01138    a = 2;
01139    b = 3;
01140    p = &b;
01141 
01142    clobber(a,p);
01143 
01144    if(a != 2 || b != 2){
01145      rc = rc+16;
01146      if(pd0->flgd != 0) printf(s71er,16);
01147    }
01148 
01149 /*   Finally, structures and unions are addressed thusly:      */
01150 
01151    if(pd0->dprec != (*pd0).dprec){
01152      rc = rc+32;
01153      if(pd0->flgd != 0) printf(s71er,32);
01154    }
01155 
01156    return rc;
01157 }
01158 McCarthy(x)
01159 int x;
01160 {
01161    if(x>100) return x-10;
01162    else return McCarthy( McCarthy(x+11));
01163 }
01164 clobber(x,y)
01165 int x, *y;
01166 {
01167    x = 3;
01168    *y = 2;
01169 }
01170 s714(pd0)          /*  7.14  Assignment operators       */
01171 struct defs *pd0;
01172 {
01173    static char f[] = "Local error %d.\n";
01174    static char s714er[] = "s714,er%d\n";
01175    static char qs714[8] = "s714   ";
01176    register int prlc, lrc;
01177    int rc;
01178    char cl, cr;
01179    short sl, sr;
01180    int il, ir;
01181    long ll, lr;
01182    unsigned ul, ur;
01183    float fl, fr;
01184    double dl, dr;
01185    char *ps, *pt;
01186    ps = qs714;
01187    pt = pd0->rfs;
01188    rc = 0;
01189    lrc = 0;
01190    prlc = pd0->flgl;
01191    while (*pt++ = *ps++);
01192 
01193         /* This section tests the assignment operators.
01194 
01195         It is an exhaustive test of all assignment statements
01196         of the form:
01197 
01198                 vl op vr
01199 
01200         where vl and vr are variables from the set
01201         {char,short,int,long,unsigned,float,double} and op is
01202         one of the assignment operators. There are 395 such
01203         statements.
01204 
01205         The initial values for the variables have been chosen
01206         so that both the initial values and the results will
01207         "fit" in just about any implementation, and that the re-
01208         sults will be such that they test for the proper form-
01209         ation of composite operators, rather than checking for
01210         the valid operation of those operators' components.
01211         For example, in checking >>=, we want to verify that
01212         a right shift and a move take place, rather than
01213         whether or not there may be some peculiarities about
01214         the right shift. Such tests have been made previously,
01215         and to repeat them here would be to throw out a red
01216         herring.
01217 
01218         The table below lists the operators, assignment targets,
01219         initial values for left and right operands, and the
01220         expected values of the results.
01221 
01222 
01223           =  +=  -=  *=  /=  %=  >>=  <<=  &=  ^=  |=   
01224 char      2   7   3  10   2   1   1    20   8   6  14
01225 short     2   7   3  10   2   1   1    20   8   6  14
01226 int       2   7   3  10   2   1   1    20   8   6  14
01227 long      2   7   3  10   2   1   1    20   8   6  14
01228 unsigned  2   7   3  10   2   1   1    20   8   6  14
01229 float     2   7   3  10 2.5 |             |
01230 double    2   7   3  10 2.5 |             |
01231                             |             |
01232 initial         (5,2)       |    (5,2)    |  (12,10)
01233 
01234         The following machine-generated program reflects the
01235         tests described in the table.
01236                                                                 */
01237 
01238    cl = 5; cr = 2;
01239    cl = cr;
01240    if(cl != 2){
01241      lrc = 1;
01242      if(prlc) printf(f,lrc);
01243    }
01244    cl = 5; sr = 2;
01245    cl = sr;
01246    if(cl != 2){
01247      lrc = 2;
01248      if(prlc) printf(f,lrc);
01249    }
01250    cl = 5; ir = 2;
01251    cl = ir;
01252    if(cl != 2){
01253      lrc = 3;
01254      if(prlc) printf(f,lrc);
01255    }
01256    cl = 5; lr = 2;
01257    cl = lr;
01258    if(cl != 2){
01259      lrc = 4;
01260      if(prlc) printf(f,lrc);
01261    }
01262    cl = 5; ur = 2;
01263    cl = ur;
01264    if(cl != 2){
01265      lrc = 5;
01266      if(prlc) printf(f,lrc);
01267    }
01268    cl = 5; fr = 2;
01269    cl = fr;
01270    if(cl != 2){
01271      lrc = 6;
01272      if(prlc) printf(f,lrc);
01273    }
01274    cl = 5; dr = 2;
01275    cl = dr;
01276    if(cl != 2){
01277      lrc = 7;
01278      if(prlc) printf(f,lrc);
01279    }
01280    sl = 5; cr = 2;
01281    sl = cr;
01282    if(sl != 2){
01283      lrc = 8;
01284      if(prlc) printf(f,lrc);
01285    }
01286    sl = 5; sr = 2;
01287    sl = sr;
01288    if(sl != 2){
01289      lrc = 9;
01290      if(prlc) printf(f,lrc);
01291    }
01292    sl = 5; ir = 2;
01293    sl = ir;
01294    if(sl != 2){
01295      lrc = 10;
01296      if(prlc) printf(f,lrc);
01297    }
01298    sl = 5; lr = 2;
01299    sl = lr;
01300    if(sl != 2){
01301      lrc = 11;
01302      if(prlc) printf(f,lrc);
01303    }
01304    sl = 5; ur = 2;
01305    sl = ur;
01306    if(sl != 2){
01307      lrc = 12;
01308      if(prlc) printf(f,lrc);
01309    }
01310    sl = 5; fr = 2;
01311    sl = fr;
01312    if(sl != 2){
01313      lrc = 13;
01314      if(prlc) printf(f,lrc);
01315    }
01316    sl = 5; dr = 2;
01317    sl = dr;
01318    if(sl != 2){
01319      lrc = 14;
01320      if(prlc) printf(f,lrc);
01321    }
01322    il = 5; cr = 2;
01323    il = cr;
01324    if(il != 2){
01325      lrc = 15;
01326      if(prlc) printf(f,lrc);
01327    }
01328    il = 5; sr = 2;
01329    il = sr;
01330    if(il != 2){
01331      lrc = 16;
01332      if(prlc) printf(f,lrc);
01333    }
01334    il = 5; ir = 2;
01335    il = ir;
01336    if(il != 2){
01337      lrc = 17;
01338      if(prlc) printf(f,lrc);
01339    }
01340    il = 5; lr = 2;
01341    il = lr;
01342    if(il != 2){
01343      lrc = 18;
01344      if(prlc) printf(f,lrc);
01345    }
01346    il = 5; ur = 2;
01347    il = ur;
01348    if(il != 2){
01349      lrc = 19;
01350      if(prlc) printf(f,lrc);
01351    }
01352    il = 5; fr = 2;
01353    il = fr;
01354    if(il != 2){
01355      lrc = 20;
01356      if(prlc) printf(f,lrc);
01357    }
01358    il = 5; dr = 2;
01359    il = dr;
01360    if(il != 2){
01361      lrc = 21;
01362      if(prlc) printf(f,lrc);
01363    }
01364    ll = 5; cr = 2;
01365    ll = cr;
01366    if(ll != 2){
01367      lrc = 22;
01368      if(prlc) printf(f,lrc);
01369    }
01370    ll = 5; sr = 2;
01371    ll = sr;
01372    if(ll != 2){
01373      lrc = 23;
01374      if(prlc) printf(f,lrc);
01375    }
01376    ll = 5; ir = 2;
01377    ll = ir;
01378    if(ll != 2){
01379      lrc = 24;
01380      if(prlc) printf(f,lrc);
01381    }
01382    ll = 5; lr = 2;
01383    ll = lr;
01384    if(ll != 2){
01385      lrc = 25;
01386      if(prlc) printf(f,lrc);
01387    }
01388    ll = 5; ur = 2;
01389    ll = ur;
01390    if(ll != 2){
01391      lrc = 26;
01392      if(prlc) printf(f,lrc);
01393    }
01394    ll = 5; fr = 2;
01395    ll = fr;
01396    if(ll != 2){
01397      lrc = 27;
01398      if(prlc) printf(f,lrc);
01399    }
01400    ll = 5; dr = 2;
01401    ll = dr;
01402    if(ll != 2){
01403      lrc = 28;
01404      if(prlc) printf(f,lrc);
01405    }
01406    ul = 5; cr = 2;
01407    ul = cr;
01408    if(ul != 2){
01409      lrc = 29;
01410      if(prlc) printf(f,lrc);
01411    }
01412    ul = 5; sr = 2;
01413    ul = sr;
01414    if(ul != 2){
01415      lrc = 30;
01416      if(prlc) printf(f,lrc);
01417    }
01418    ul = 5; ir = 2;
01419    ul = ir;
01420    if(ul != 2){
01421      lrc = 31;
01422      if(prlc) printf(f,lrc);
01423    }
01424    ul = 5; lr = 2;
01425    ul = lr;
01426    if(ul != 2){
01427      lrc = 32;
01428      if(prlc) printf(f,lrc);
01429    }
01430    ul = 5; ur = 2;
01431    ul = ur;
01432    if(ul != 2){
01433      lrc = 33;
01434      if(prlc) printf(f,lrc);
01435    }
01436    ul = 5; fr = 2;
01437    ul = fr;
01438    if(ul != 2){
01439      lrc = 34;
01440      if(prlc) printf(f,lrc);
01441    }
01442    ul = 5; dr = 2;
01443    ul = dr;
01444    if(ul != 2){
01445      lrc = 35;
01446      if(prlc) printf(f,lrc);
01447    }
01448    fl = 5; cr = 2;
01449    fl = cr;
01450    if(fl != 2){
01451      lrc = 36;
01452      if(prlc) printf(f,lrc);
01453    }
01454    fl = 5; sr = 2;
01455    fl = sr;
01456    if(fl != 2){
01457      lrc = 37;
01458      if(prlc) printf(f,lrc);
01459    }
01460    fl = 5; ir = 2;
01461    fl = ir;
01462    if(fl != 2){
01463      lrc = 38;
01464      if(prlc) printf(f,lrc);
01465    }
01466    fl = 5; lr = 2;
01467    fl = lr;
01468    if(fl != 2){
01469      lrc = 39;
01470      if(prlc) printf(f,lrc);
01471    }
01472    fl = 5; ur = 2;
01473    fl = ur;
01474    if(fl != 2){
01475      lrc = 40;
01476      if(prlc) printf(f,lrc);
01477    }
01478    fl = 5; fr = 2;
01479    fl = fr;
01480    if(fl != 2){
01481      lrc = 41;
01482      if(prlc) printf(f,lrc);
01483    }
01484    fl = 5; dr = 2;
01485    fl = dr;
01486    if(fl != 2){
01487      lrc = 42;
01488      if(prlc) printf(f,lrc);
01489    }
01490    dl = 5; cr = 2;
01491    dl = cr;
01492    if(dl != 2){
01493      lrc = 43;
01494      if(prlc) printf(f,lrc);
01495    }
01496    dl = 5; sr = 2;
01497    dl = sr;
01498    if(dl != 2){
01499      lrc = 44;
01500      if(prlc) printf(f,lrc);
01501    }
01502    dl = 5; ir = 2;
01503    dl = ir;
01504    if(dl != 2){
01505      lrc = 45;
01506      if(prlc) printf(f,lrc);
01507    }
01508    dl = 5; lr = 2;
01509    dl = lr;
01510    if(dl != 2){
01511      lrc = 46;
01512      if(prlc) printf(f,lrc);
01513    }
01514    dl = 5; ur = 2;
01515    dl = ur;
01516    if(dl != 2){
01517      lrc = 47;
01518      if(prlc) printf(f,lrc);
01519    }
01520    dl = 5; fr = 2;
01521    dl = fr;
01522    if(dl != 2){
01523      lrc = 48;
01524      if(prlc) printf(f,lrc);
01525    }
01526    dl = 5; dr = 2;
01527    dl = dr;
01528    if(dl != 2){
01529      lrc = 49;
01530      if(prlc) printf(f,lrc);
01531    }
01532    cl = 5; cr = 2;
01533    cl += cr;
01534    if(cl != 7){
01535      lrc = 50;
01536      if(prlc) printf(f,lrc);
01537    }
01538    cl = 5; sr = 2;
01539    cl += sr;
01540    if(cl != 7){
01541      lrc = 51;
01542      if(prlc) printf(f,lrc);
01543    }
01544    cl = 5; ir = 2;
01545    cl += ir;
01546    if(cl != 7){
01547      lrc = 52;
01548      if(prlc) printf(f,lrc);
01549    }
01550    cl = 5; lr = 2;
01551    cl += lr;
01552    if(cl != 7){
01553      lrc = 53;
01554      if(prlc) printf(f,lrc);
01555    }
01556    cl = 5; ur = 2;
01557    cl += ur;
01558    if(cl != 7){
01559      lrc = 54;
01560      if(prlc) printf(f,lrc);
01561    }
01562    cl = 5; fr = 2;
01563    cl += fr;
01564    if(cl != 7){
01565      lrc = 55;
01566      if(prlc) printf(f,lrc);
01567    }
01568    cl = 5; dr = 2;
01569    cl += dr;
01570    if(cl != 7){
01571      lrc = 56;
01572      if(prlc) printf(f,lrc);
01573    }
01574    sl = 5; cr = 2;
01575    sl += cr;
01576    if(sl != 7){
01577      lrc = 57;
01578      if(prlc) printf(f,lrc);
01579    }
01580    sl = 5; sr = 2;
01581    sl += sr;
01582    if(sl != 7){
01583      lrc = 58;
01584      if(prlc) printf(f,lrc);
01585    }
01586    sl = 5; ir = 2;
01587    sl += ir;
01588    if(sl != 7){
01589      lrc = 59;
01590      if(prlc) printf(f,lrc);
01591    }
01592    sl = 5; lr = 2;
01593    sl += lr;
01594    if(sl != 7){
01595      lrc = 60;
01596      if(prlc) printf(f,lrc);
01597    }
01598    sl = 5; ur = 2;
01599    sl += ur;
01600    if(sl != 7){
01601      lrc = 61;
01602      if(prlc) printf(f,lrc);
01603    }
01604    sl = 5; fr = 2;
01605    sl += fr;
01606    if(sl != 7){
01607      lrc = 62;
01608      if(prlc) printf(f,lrc);
01609    }
01610    sl = 5; dr = 2;
01611    sl += dr;
01612    if(sl != 7){
01613      lrc = 63;
01614      if(prlc) printf(f,lrc);
01615    }
01616    il = 5; cr = 2;
01617    il += cr;
01618    if(il != 7){
01619      lrc = 64;
01620      if(prlc) printf(f,lrc);
01621    }
01622    il = 5; sr = 2;
01623    il += sr;
01624    if(il != 7){
01625      lrc = 65;
01626      if(prlc) printf(f,lrc);
01627    }
01628    il = 5; ir = 2;
01629    il += ir;
01630    if(il != 7){
01631      lrc = 66;
01632      if(prlc) printf(f,lrc);
01633    }
01634    il = 5; lr = 2;
01635    il += lr;
01636    if(il != 7){
01637      lrc = 67;
01638      if(prlc) printf(f,lrc);
01639    }
01640    il = 5; ur = 2;
01641    il += ur;
01642    if(il != 7){
01643      lrc = 68;
01644      if(prlc) printf(f,lrc);
01645    }
01646    il = 5; fr = 2;
01647    il += fr;
01648    if(il != 7){
01649      lrc = 69;
01650      if(prlc) printf(f,lrc);
01651    }
01652    il = 5; dr = 2;
01653    il += dr;
01654    if(il != 7){
01655      lrc = 70;
01656      if(prlc) printf(f,lrc);
01657    }
01658    ll = 5; cr = 2;
01659    ll += cr;
01660    if(ll != 7){
01661      lrc = 71;
01662      if(prlc) printf(f,lrc);
01663    }
01664    ll = 5; sr = 2;
01665    ll += sr;
01666    if(ll != 7){
01667      lrc = 72;
01668      if(prlc) printf(f,lrc);
01669    }
01670    ll = 5; ir = 2;
01671    ll += ir;
01672    if(ll != 7){
01673      lrc = 73;
01674      if(prlc) printf(f,lrc);
01675    }
01676    ll = 5; lr = 2;
01677    ll += lr;
01678    if(ll != 7){
01679      lrc = 74;
01680      if(prlc) printf(f,lrc);
01681    }
01682    ll = 5; ur = 2;
01683    ll += ur;
01684    if(ll != 7){
01685      lrc = 75;
01686      if(prlc) printf(f,lrc);
01687    }
01688    ll = 5; fr = 2;
01689    ll += fr;
01690    if(ll != 7){
01691      lrc = 76;
01692      if(prlc) printf(f,lrc);
01693    }
01694    ll = 5; dr = 2;
01695    ll += dr;
01696    if(ll != 7){
01697      lrc = 77;
01698      if(prlc) printf(f,lrc);
01699    }
01700    ul = 5; cr = 2;
01701    ul += cr;
01702    if(ul != 7){
01703      lrc = 78;
01704      if(prlc) printf(f,lrc);
01705    }
01706    ul = 5; sr = 2;
01707    ul += sr;
01708    if(ul != 7){
01709      lrc = 79;
01710      if(prlc) printf(f,lrc);
01711    }
01712    ul = 5; ir = 2;
01713    ul += ir;
01714    if(ul != 7){
01715      lrc = 80;
01716      if(prlc) printf(f,lrc);
01717    }
01718    ul = 5; lr = 2;
01719    ul += lr;
01720    if(ul != 7){
01721      lrc = 81;
01722      if(prlc) printf(f,lrc);
01723    }
01724    ul = 5; ur = 2;
01725    ul += ur;
01726    if(ul != 7){
01727      lrc = 82;
01728      if(prlc) printf(f,lrc);
01729    }
01730    ul = 5; fr = 2;
01731    ul += fr;
01732    if(ul != 7){
01733      lrc = 83;
01734      if(prlc) printf(f,lrc);
01735    }
01736    ul = 5; dr = 2;
01737    ul += dr;
01738    if(ul != 7){
01739      lrc = 84;
01740      if(prlc) printf(f,lrc);
01741    }
01742    fl = 5; cr = 2;
01743    fl += cr;
01744    if(fl != 7){
01745      lrc = 85;
01746      if(prlc) printf(f,lrc);
01747    }
01748    fl = 5; sr = 2;
01749    fl += sr;
01750    if(fl != 7){
01751      lrc = 86;
01752      if(prlc) printf(f,lrc);
01753    }
01754    fl = 5; ir = 2;
01755    fl += ir;
01756    if(fl != 7){
01757      lrc = 87;
01758      if(prlc) printf(f,lrc);
01759    }
01760    fl = 5; lr = 2;
01761    fl += lr;
01762    if(fl != 7){
01763      lrc = 88;
01764      if(prlc) printf(f,lrc);
01765    }
01766    fl = 5; ur = 2;
01767    fl += ur;
01768    if(fl != 7){
01769      lrc = 89;
01770      if(prlc) printf(f,lrc);
01771    }
01772    fl = 5; fr = 2;
01773    fl += fr;
01774    if(fl != 7){
01775      lrc = 90;
01776      if(prlc) printf(f,lrc);
01777    }
01778    fl = 5; dr = 2;
01779    fl += dr;
01780    if(fl != 7){
01781      lrc = 91;
01782      if(prlc) printf(f,lrc);
01783    }
01784    dl = 5; cr = 2;
01785    dl += cr;
01786    if(dl != 7){
01787