Annotation of 42BSD/ingres/doc/other/example.c, revision 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.