Annotation of 42BSD/ingres/doc/other/example.c, revision 1.1.1.1

1.1       root        1: # include      "/usr/sys/param.h"
                      2: 
                      3: /*
                      4: **  DEMO PROGRAM
                      5: **
                      6: **     This hunk of code does virtually nothing of use.  Its main
                      7: **     purpose is to demonstrate the "official" ingres coding style.
                      8: **
                      9: **     This demonstrates comments.  There should be a block comment
                     10: **     at the beginning of every file and/or procedure to explain
                     11: **     the function of the code.  Important information to put here
                     12: **     includes the parameters of the routines, any options that the
                     13: **     user may specify, etc.
                     14: **
                     15: **     The first line of the comment should be a one-line description
                     16: **     of what's going on.  The remainder should be more detailed.
                     17: **     Blank lines should seperate major points in the comments.  In
                     18: **     general, ask yourself the question, "If I didn't know what this
                     19: **     code was, what it was for, how it fit in, etc., and if I didn't
                     20: **     even have the documentation for it, would these comments be
                     21: **     enough for me?"
                     22: **
                     23: **     Some general guidelines for the code:
                     24: **
                     25: **     - Commas and semicolons should always be followed by a space.
                     26: **             Binary operators should be surrounded on both sides by
                     27: **             spaces.  Unary operators should be in direct contact
                     28: **             with the object that they act on, except for "sizeof",
                     29: **             which should be seperated by one space.
                     30: **
                     31: **     - Two statements should never go on the same line.  This includes
                     32: **             such things as an if and the associated conditionally
                     33: **             executed statement.
                     34: **             In cases such as this, the second half of the if
                     35: **             should be indented one tab stop more than the if.  For
                     36: **             example, use:
                     37: **                     if (cond)
                     38: **                             statement;
                     39: **             never:
                     40: **                     if (cond) statement;
                     41: **             or:
                     42: **                     if (cond)
                     43: **                     statement;
                     44: **
                     45: **     - Braces ({}) should (almost) always be on a line by them-
                     46: **             selves.  Exceptions are closing a do, and terminating
                     47: **             a struct definition or variable initialization.  Braces
                     48: **             should start at the same indent as the statement with
                     49: **             which they bind, and code inside the braces should be
                     50: **             indented one stop further.  For example, use:
                     51: **                     while (cond)
                     52: **                     {
                     53: **                             code
                     54: **                     }
                     55: **             and never:
                     56: **                     while (cond)
                     57: **                             {
                     58: **                             code
                     59: **                             }
                     60: **             or:
                     61: **                     while (cond) {
                     62: **                             code
                     63: **                     }
                     64: **             or:
                     65: **                     while (cond)
                     66: **                     {
                     67: **                     code
                     68: **                     }
                     69: **             or anything else in that line.  Braces which match
                     70: **             should always be at the same tab stop.
                     71: **
                     72: **     - Declarations should always have at least one tab between the
                     73: **             declaration part and the variable list part, but never
                     74: **             any tabs within the declaration part or the variable
                     75: **             list part.  For example, in the line:
                     76: **                     register int    i, j;
                     77: **             There is a tab between the "int" and the "i", but a
                     78: **             space between "register" and "int", since together
                     79: **             these make up the declaration part.
                     80: **
                     81: **     - There should always be a space following a keyword (i.e.,
                     82: **             for, if, do, while, switch, and return), but never 
                     83: **             between a function and the paren preceeding its
                     84: **             arguments.  For example, use:
                     85: **                     if (i == 0)
                     86: **                             exit();
                     87: **             never:
                     88: **                     if(i == 0)
                     89: **                             exit ();
                     90: **
                     91: **     - Every case in a switch statement (including default) should
                     92: **             be preceeded by a blank line.  The actual word "case" or
                     93: **             "default" should have the indent of the switch statement plus
                     94: **             two spaces.  It should be followed by a space (not a
                     95: **             tab) and the case constant.  Multiple case labels on
                     96: **             a single block of code should be on seperate lines, but
                     97: **             they should not be seperated by blank lines.  The
                     98: **             switch statement should in general be used in place of
                     99: **             such constructs as:
                    100: **                     if (i == 1)
                    101: **                             code1;
                    102: **                     else
                    103: **                             if (i == 34)
                    104: **                                     code2;
                    105: **                             else
                    106: **                                     if (i == -1643)
                    107: **                                             code3;
                    108: **             which can be more succinctly stated as:
                    109: **                     switch (i)
                    110: **                     {
                    111: **
                    112: **                       case 1:
                    113: **                             code1;
                    114: **                             break;
                    115: **
                    116: **                       case 34:
                    117: **                             code2;
                    118: **                             break;
                    119: **
                    120: **                       case -1643:
                    121: **                             code3;
                    122: **                             break;
                    123: **
                    124: **                     }
                    125: **             In point of fact the equivalent switch will compile
                    126: **             extremely efficiently.  (Note that if you had some
                    127: **             instance where you could not use a case, e.g., checking
                    128: **             for i < 5, else check for j > 3, else whatever, then
                    129: **             the above ("if") code is in the correct style.  However,
                    130: **             an acceptable alternate structure is to consider "else if"
                    131: **             as a primitive.  Hence:
                    132: **                     if (i < 5)
                    133: **                             code1;
                    134: **                     else if (j > 3)
                    135: **                             code2;
                    136: **                     else
                    137: **                             code3;
                    138: **             is acceptable.
                    139: **
                    140: **     - Do statements must always be of the form:
                    141: **                     do
                    142: **                     {
                    143: **                             code;
                    144: **                     } while (cond);
                    145: **             even if "code" is only one line.  This is done so that
                    146: **             it is clear that the "while" is with a do, rather than
                    147: **             a standalone "while" which is used for the side effects of
                    148: **             evaluation of the condition.
                    149: **
                    150: **     - Defined constants (defined with the # define feature) must
                    151: **             be entirely upper case.  The exceptions to this are
                    152: **             compilation flags, which begin with a lower case "x",
                    153: **             and some sub-types for parser symbols.  In any case,
                    154: **             the majority of the symbol is upper case.
                    155: **
                    156: **     - Global variables should begin with an upper case letter and
                    157: **             be otherwise all lower case.  Local symbols should be
                    158: **             entirely lower case.  Procedure names are all lower
                    159: **             case.  The only exception to this is the trace routine
                    160: **             "tTf".  You should avoid user non-local symbols (globals
                    161: **             or # define'd symbols) which are one character only;
                    162: **             it is impossible to distinguish them.
                    163: **
                    164: **     - # defines and # includes should have a space after the sharp
                    165: **             sign and be followed by a tab.  In general, try to make
                    166: **             things line up.  Use:
                    167: **                     # define        ARPA            25
                    168: **                     # define        MAXFIELDS       18
                    169: **             and not:
                    170: **                     #define ARPA 25
                    171: **                     #define MAXFIELDS 18
                    172: **             Conditional compilation statements should have as many
                    173: **             tabs as are necessary to bring the "ifdef",
                    174: **             "ifndef", or "endif" to the tab stop of the surrounding
                    175: **             code.  The keyword ("ifdef" or "ifndef") should be
                    176: **             followed by a space and the conditional compilation
                    177: **             variable.  Conditional compilation should be used
                    178: **             around all trace information, timing code, and code
                    179: **             which may vary from version to version of UNIX.  See
                    180: **             the code below for an example of conditional compila-
                    181: **             tion use.
                    182: **
                    183: **     - A blank line should seperate the declarations and the code
                    184: **             in a procedure.  Blank lines should also be used freely
                    185: **             between major subsections of your code.  The major
                    186: **             subsections should also have a comment giving some idea
                    187: **             of what is about to occur.
                    188: **
                    189: **     - Use descriptive variable names, particularly for global var-
                    190: **             iables.  "IEH3462" tells me nothing; nor does "R".  On
                    191: **             the other hand, "Resultid" tells me quite a lot,
                    192: **             including what it might be, where I might go to see
                    193: **             how it is initialized, etc.  Try not to use variables
                    194: **             for multiple purposes.
                    195: **
                    196: **     - It is quite possible to name a file "printr.c" and then
                    197: **             put the code for "destroydb" in it.  Try to arrange
                    198: **             the names of your files so that given the name of a
                    199: **             routine, it is fairly easy to figure out which file
                    200: **             it is in.
                    201: **
                    202: **     - Sometimes it is really pretty much impossible to avoid doing
                    203: **             something which is not immediately obvious.  In these
                    204: **             cases, put in a comment telling what you are doing and
                    205: **             why you are doing it.
                    206: **
                    207: **     - Try to write things that are clear, rather than things which
                    208: **             you think are easier to compile.  I mean, who really
                    209: **             cares?  For example, always declare temporary buffers
                    210: **             as local, rather than as global.  This way you can
                    211: **             guarantee that you will never clobber the buffer in
                    212: **             another routine accidently when it still had useful
                    213: **             info in it.
                    214: **
                    215: **     Remember, it is easy to write incomprehensible code in
                    216: **     C.  If you really get off on doing this, however, go get
                    217: **     a job programming in APL.
                    218: **
                    219: **     For efficiency reasons, you should always use register variables
                    220: **     when possible.  A simple and extremely effective tip is to define
                    221: **     a register variable, and assign an oft-used parameter to it,
                    222: **     since it is particularly inefficient to reference a parameter.
                    223: **     Another particularly inefficient operation is referencing arrays
                    224: **     of structures.  When possible, define a register pointer to the
                    225: **     structure, and then say:
                    226: **             struct xyz              structure[MAX];
                    227: **             register struct xyz     *p;
                    228: **             ...
                    229: **             for (i = 0; i < MAX; i++)
                    230: **             {
                    231: **                     p = &structure[i];
                    232: **                     p->x = p->y + p->z;
                    233: **                     (diddle with p->???)
                    234: **             }
                    235: **     and not:
                    236: **             struct xyz              structure[MAX];
                    237: **             ...
                    238: **             for (i = 0; i < MAX; i++)
                    239: **             {
                    240: **                     Structure[i].x = Structure[i].y + Structure[i].z;
                    241: **                     (diddle with Structure[i].???)
                    242: **             }
                    243: **     Remember, the nice things about register variables is that they
                    244: **     make your code smaller and they run faster.  It is hard to
                    245: **     lose with registers.  There are three restrictions which you
                    246: **     should be aware of on register variables, however.  First,
                    247: **     The only types which may be registers are int's, char's,
                    248: **     and pointers.  Second, there may only be three register
                    249: **     variables per subroutine.  Third, you may not take the address
                    250: **     of a register variable (i.e., you may not say "&i" if i is
                    251: **     typed as a register variable).
                    252: */
                    253: 
                    254: 
                    255: # define       XEQ1            5
                    256: 
                    257: struct magic
                    258: {
                    259:        char    *name;          /* name of symbol */
                    260:        int     type;           /* type of symbol, defined in symbol.h */
                    261:        int     value;          /* optional value.  This is actually
                    262:                                 * the value if it is type "integer",
                    263:                                 * a pointer to the value if it is a
                    264:                                 * string. */
                    265: };
                    266: 
                    267: struct magic   Stuff;
                    268: 
                    269: main(argc, argv)
                    270: int    argc;
                    271: char   *argv[];
                    272: {
                    273:        register struct magic   *r;
                    274:        register int            i;
                    275:        register int            j;
                    276:        int                     timebuf[2];
                    277:        int                     status;
                    278: 
                    279:        /* Note that in the declarations of argc and argv above, all
                    280:         * parameters to any function should be declared, even if they
                    281:         * are of type int (which is the default). */
                    282: 
                    283:        r = &Stuff;
                    284:        /* initialize random # generator */
                    285:        time(timebuf);
                    286:        srand(timebuf[1]);
                    287: 
                    288:        /* scan Stuff structure */
                    289:        for (i = 0; i < XEQ1; i++)
                    290:        {
                    291: #              ifdef xTRACE
                    292:                if (tTf(5, 13))
                    293:                        printf("switch on type %d\n", r->reltype);
                    294: #              endif
                    295:                switch (r->type)
                    296:                {
                    297: 
                    298:                  case 0:
                    299:                  case 1:
                    300:                  case 3:
                    301:                        /* initialize */
                    302:                        printf("hi\n");
                    303:                        break;
                    304: 
                    305:                  case 2:
                    306:                        /* end of query */
                    307:                        printf("bye\n");
                    308:                        break;
                    309: 
                    310:                  default:
                    311:                        /* be sure to print plenty of info on an error;
                    312:                         * "syserr("bad reltype");" would not have been
                    313:                         * sufficient */
                    314:                        syserr("bad type %d", r->type);
                    315: 
                    316:                }
                    317:        }
                    318: 
                    319:        /* resist the temptation to say "} else {" */
                    320:        if (i == 5)
                    321:        {
                    322:                i++;
                    323:                j = 4;
                    324:        }
                    325:        else
                    326:                i--;
                    327: 
                    328:        /* plot the results */
                    329:        do
                    330:        {
                    331:                i = rand() & 017;
                    332:                while (i--)
                    333:                {
                    334:                        printf("*");
                    335:                }
                    336:                printf("\n");
                    337:        } while (j--);
                    338: 
                    339:        /* wait for child processes to complete */
                    340:        wait(&status);
                    341:        /* end of run, print termination message and exit */
                    342:        for (i = 0; i < 2; i++)
                    343:                printf("bye ");
                    344:        printf("\n");
                    345: }

unix.superglobalmegacorp.com

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