Annotation of 43BSD/ingres/doc/other/code_cnvntns.c, revision 1.1.1.1

1.1       root        1: # include      "/usr/sys/param.h"
                      2: # include      <sccs.h>
                      3: 
                      4: /*
                      5: **  CODE_CNVNTNS.C -- A Program to Display the INGRES Coding Style
                      6: **
                      7: **     This hunk of code does virtually nothing of use.  Its main
                      8: **     purpose is to demonstrate the "official" ingres coding style.
                      9: **
                     10: **     This demonstrates comments.  There should be a block comment
                     11: **     at the beginning of every file and/or procedure to explain
                     12: **     the function of the code.  Important information to put here
                     13: **     includes the parameters of the routines, any options that the
                     14: **     user may specify, etc.
                     15: **
                     16: **     The first line of the comment should be a one-line description
                     17: **     of what's going on.  The remainder should be more detailed.
                     18: **     Blank lines should separate major points in the comments.  In
                     19: **     general, ask yourself the question, "If I didn't know what this
                     20: **     code was, what it was for, how it fit in, etc., and if I didn't
                     21: **     even have the documentation for it, would these comments be
                     22: **     enough for me?"
                     23: **
                     24: **     Some general guidelines for the code:
                     25: **
                     26: **     *****  GENERAL SYNTAX  *****
                     27: **
                     28: **     - Commas and semicolons should always be followed by a space.
                     29: **             Binary operators should be surrounded on both sides by
                     30: **             spaces.  Unary operators should be in direct contact
                     31: **             with the object that they act on, except for "sizeof",
                     32: **             which should be separated by one space.
                     33: **
                     34: **     - Two statements should never go on the same line.  This includes
                     35: **             such things as an if and the associated conditionally
                     36: **             executed statement.
                     37: **             In cases such as this, the second half of the if
                     38: **             should be indented one tab stop more than the if.  For
                     39: **             example, use:
                     40: **                     if (cond)
                     41: **                             statement;
                     42: **             never:
                     43: **                     if (cond) statement;
                     44: **             or:
                     45: **                     if (cond)
                     46: **                     statement;
                     47: **
                     48: **     - Braces ({}) should (almost) always be on a line by them-
                     49: **             selves.  Exceptions are closing a do, and terminating
                     50: **             a struct definition or variable initialization.  Braces
                     51: **             should start at the same indent as the statement with
                     52: **             which they bind, and code inside the braces should be
                     53: **             indented one stop further.  For example, use:
                     54: **                     while (cond)
                     55: **                     {
                     56: **                             code
                     57: **                     }
                     58: **             and never:
                     59: **                     while (cond)
                     60: **                             {
                     61: **                             code
                     62: **                             }
                     63: **             or:
                     64: **                     while (cond) {
                     65: **                             code
                     66: **                     }
                     67: **             or:
                     68: **                     while (cond)
                     69: **                     {
                     70: **                     code
                     71: **                     }
                     72: **             or anything else in that line.  Braces which match
                     73: **             should always be at the same tab stop.
                     74: **
                     75: **     - Do statements must always be of the form:
                     76: **                     do
                     77: **                     {
                     78: **                             code;
                     79: **                     } while (cond);
                     80: **             even if "code" is only one line.  This is done so that
                     81: **             it is clear that the "while" is with a do, rather than
                     82: **             a standalone "while" which is used for the side effects of
                     83: **             evaluation of the condition.
                     84: **
                     85: **     - There should always be a space following a keyword (i.e.,
                     86: **             for, if, do, while, switch, and return), but never 
                     87: **             between a function and the paren preceeding its
                     88: **             arguments.  For example, use:
                     89: **                     if (i == 0)
                     90: **                             exit();
                     91: **             never:
                     92: **                     if(i == 0)
                     93: **                             exit ();
                     94: **
                     95: **     - Every case in a switch statement (including default) should
                     96: **             be preceeded by a blank line.  The actual word "case" or
                     97: **             "default" should have the indent of the switch statement plus
                     98: **             two spaces.  It should be followed by a space (not a
                     99: **             tab) and the case constant.  Multiple case labels on
                    100: **             a single block of code should be on separate lines, but
                    101: **             they should not be separated by blank lines.  The
                    102: **             switch statement should in general be used in place of
                    103: **             such constructs as:
                    104: **                     if (i == 1)
                    105: **                             code1;
                    106: **                     else if (i == 34)
                    107: **                             code2;
                    108: **                     else if (i == -1643)
                    109: **                             code3;
                    110: **             which can be more succinctly stated as:
                    111: **                     switch (i)
                    112: **                     {
                    113: **                       case 1:
                    114: **                             code1;
                    115: **                             break;
                    116: **
                    117: **                       case 34:
                    118: **                             code2;
                    119: **                             break;
                    120: **
                    121: **                       case -1643:
                    122: **                             code3;
                    123: **                             break;
                    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: **                     if (i < 5)
                    131: **                             code1;
                    132: **                     else
                    133: **                             if (j > 3)
                    134: **                                     code2;
                    135: **                             else
                    136: **                                     code3;
                    137: **             is acceptable.
                    138: **
                    139: **     - A blank line should separate the declarations and the code
                    140: **             in a procedure.  Blank lines should also be used freely
                    141: **             between major subsections of your code.  The major
                    142: **             subsections should also have a block comment giving
                    143: **             some idea of what is about to occur.
                    144: **
                    145: **     *****  PREPROCESSOR USAGE  *****
                    146: **
                    147: **     - Fields of #defines and #includes should line up.  Use:
                    148: **                     # define        ARPA            25
                    149: **                     # define        MAXFIELDS       18
                    150: **             and not:
                    151: **                     #define ARPA 25
                    152: **                     #define MAXFIELDS 18
                    153: **             Conditional compilation (#ifdef/#endif) should be used
                    154: **             around all trace information, timing code, and code
                    155: **             which may vary from version to version of UNIX.  See
                    156: **             the code below for an example of conditional compila-
                    157: **             tion use.
                    158: **
                    159: **     *****  VARIABLES AND DECLARATIONS  *****
                    160: **
                    161: **     - Defined constants (defined with the # define feature) must
                    162: **             be entirely upper case.  The exceptions to this are
                    163: **             compilation flags, which begin with a lower case "x",
                    164: **             and some sub-types for parser symbols.  In any case,
                    165: **             the majority of the symbol is upper case.
                    166: **
                    167: **     - Global variables should begin with an upper case letter and
                    168: **             be otherwise all lower case.  Local symbols should be
                    169: **             entirely lower case.  Procedure names are all lower
                    170: **             case.  The only exception to this is the trace routine
                    171: **             "tTf".  You should avoid user non-local symbols (globals
                    172: **             or # define'd symbols) which are one character only;
                    173: **             it is impossible to distinguish them.  Capitalization
                    174: **             may be used freely inside global names so long as they
                    175: **             are primarily lower case; for example, "ProcName" is
                    176: **             an acceptable name (and preferred over either Proc_name
                    177: **             or Procname).
                    178: **
                    179: **     - Use descriptive variable names, particularly for global var-
                    180: **             iables.  "IEH3462" tells me nothing; nor does "R".  On
                    181: **             the other hand, "Resultid" tells me quite a lot,
                    182: **             including what it might be, where I might go to see
                    183: **             how it is initialized, etc.  Try not to use variables
                    184: **             for multiple purposes.  Variable names like "i" are
                    185: **             acceptable for loop indices & temporary storage
                    186: **             provided that the value does not have long-term
                    187: **             semantic value.
                    188: **
                    189: **     - When the storage structure or type of a variable is
                    190: **             important, always state it explicitly.  In particular,
                    191: **             include "auto" if you are going to take the address
                    192: **             of something using the ampersand operator (so that
                    193: **             some wayward programmer doesn't change it to register),
                    194: **             and declare int parameters as int instead of letting
                    195: **             them default.
                    196: **
                    197: **     *****  GENERAL COMMENTS  *****
                    198: **
                    199: **     - It is quite possible to name a file "printr.c" and then
                    200: **             put the code for "destroydb" in it.  Try to arrange
                    201: **             the names of your files so that given the name of a
                    202: **             routine, it is fairly easy to figure out which file
                    203: **             it is in.
                    204: **
                    205: **     - Sometimes it is really pretty much impossible to avoid doing
                    206: **             something tricky.  In these cases, put in a comment
                    207: **             telling what you are doing and why you are doing it.
                    208: **
                    209: **     - Try to write things that are clear and safe, rather than
                    210: **             things which you think are easier to compile.  For
                    211: **             example, always declare temporary buffers as local,
                    212: **             rather than as global.  This way you can another
                    213: **             routine accidently when it still had useful info
                    214: **             in it.
                    215: **
                    216: **     *****  COMMENTS  *****
                    217: **
                    218: **     - The importance of comments cannot be overemphasised.
                    219: **             INGRES is primarily a research vehicle rather than
                    220: **             a program product.  This means that there will be
                    221: **             many people pouring over your code, trying to
                    222: **             understand what you have done & modify it to do
                    223: **             other things.  Try to make life easy for them &
                    224: **             maybe they will be nice to you someday.
                    225: **     
                    226: **     - Try to keep an idea of the flow of your program.  Put
                    227: **             block comments at the beginning of major segments,
                    228: **             and use one-line comments at less major junctures.
                    229: **             A person viewing your code at ten paces should be
                    230: **             able to tell where the major segments lay.
                    231: **
                    232: **     - The preferred format for block comments is to begin with
                    233: **             a line containing slash-star alone, followed by a
                    234: **             number of lines all beginning star-star containing
                    235: **             the comment, and terminating with a line containing
                    236: **             star-slash alone.  Comments without the double-star
                    237: **             at the beginning of each line should be avoided,
                    238: **             since it makes the comments seemingly disappear into
                    239: **             the body of the code.
                    240: **
                    241: **     - The beginning of each routine should have a comment block
                    242: **             in parametric form as demonstrated below.  The fields
                    243: **             "Parameters", "Returns", and "Side Effects" should
                    244: **             be considered mandatory.  Mark parameters as being
                    245: **             (IN), (IN/OUT), or (OUT) parameters, depending on
                    246: **             whether the parameter is used only to transmit infor-
                    247: **             mation into the routine, in and out of the routine,
                    248: **             or only to return information; the default is (IN).
                    249: **
                    250: **     Remember, it is easy to write totally incomprehensible code in
                    251: **     C, but we don't go in for that sort of thing.  It isn't too
                    252: **     much harder to write brilliantly clear code, and the code is
                    253: **     worth a lot more later.
                    254: **
                    255: **     For efficiency reasons, you should always use register variables
                    256: **     when possible.  A simple and extremely effective tip is to define
                    257: **     a register variable, and assign an oft-used parameter to it,
                    258: **     since it is particularly inefficient to reference a parameter.
                    259: **     Another particularly inefficient operation is referencing arrays
                    260: **     of structures.  When possible, define a register pointer to the
                    261: **     structure, and then say:
                    262: **             struct xyz structure[MAX];
                    263: **             register struct xyz *p;
                    264: **             ...
                    265: **             for (i = 0; i < MAX; i++)
                    266: **             {
                    267: **                     p = &structure[i];
                    268: **                     p->x = p->y + p->z;
                    269: **                     (diddle with p->???)
                    270: **             }
                    271: **     and not:
                    272: **             struct xyz structure[MAX];
                    273: **             ...
                    274: **             for (i = 0; i < MAX; i++)
                    275: **             {
                    276: **                     Structure[i].x = Structure[i].y + Structure[i].z;
                    277: **                     (diddle with Structure[i].???)
                    278: **             }
                    279: **     Remember, the nice things about register variables is that they
                    280: **     make your code smaller and they run faster.  It is hard to
                    281: **     lose with registers.  There are three restrictions which you
                    282: **     should be aware of on register variables, however.  First,
                    283: **     The only types which may be registers are int's, char's,
                    284: **     and pointers.  Second, there may only be three register
                    285: **     variables per subroutine.  Third, you may not take the address
                    286: **     of a register variable (i.e., you may not say "&i" if i is
                    287: **     typed as a register variable).
                    288: **
                    289: **     Usage:
                    290: **             example [flags] argument
                    291: **
                    292: **     Positional Parameters:
                    293: **             argument -- this gets echoed to the standard
                    294: **                     output.
                    295: **
                    296: **     Flags:
                    297: **             -n -- don't put a newline at the end.
                    298: **             -x -- don't do anything.
                    299: **             -b -- echo it with a bell character.
                    300: **
                    301: **     Return Codes:
                    302: **             0 -- successful
                    303: **             else -- failure
                    304: **
                    305: **     Defined Constants:
                    306: **             XEQ1 -- maximum number of simultaneous equijoins.
                    307: **
                    308: **     Compilation Flags:
                    309: **             xTRACE -- enable trace information
                    310: **
                    311: **     Trace Flags:
                    312: **             5 -- general debug
                    313: **             6 -- reserved for future use
                    314: **
                    315: **     Compilation Instructions:
                    316: **             cc -n example.c
                    317: **             mv a.out example
                    318: **             chmod 755 example
                    319: **
                    320: **     Notes:
                    321: **             These comments don't apply to the code at all,
                    322: **                     since this is just an example program.
                    323: **             Also, it is wise to avoid this many comments
                    324: **                     except at the head of main programs and
                    325: **                     at the head of major modules.  For example,
                    326: **                     this sort of commenting is appropriate at
                    327: **                     the top of ingres.c (system startup) and
                    328: **                     view.c (virtual view subsystem), but not
                    329: **                     in small utility routines, e.g., length.c.
                    330: **                     This sort of routine should be limited to
                    331: **                     "Parameters:", "Returns:", "Side Effects:",
                    332: **                     and anything else that seems relevant in
                    333: **                     that context.
                    334: **             A fairly large comment block should exist at the
                    335: **                     top of modules [files] which contain many
                    336: **                     procedures; this block should clarify why
                    337: **                     the procedures are grouped together, that
                    338: **                     is, their common purpose in life.  A small
                    339: **                     block should occur at the top of each
                    340: **                     procedure explaining details of that proce-
                    341: **                     dure.
                    342: **             Procedures should be on separate pages (use the
                    343: **                     form feed character, control-L).
                    344: **             A program will help you generate this comment block.
                    345: **                     In ex, go to the line where you want to insert
                    346: **                     a block and say "so /mnt/ingres/comment".  It
                    347: **                     will ask you for a block type, e.g., "main"
                    348: **                     for main program, "modfn" for a file which
                    349: **                     contains only one function, "function" or
                    350: **                     "procedure" for a procedure within a module,
                    351: **                     "module" for a module header (e.g., as a
                    352: **                     separate comment block for a major module
                    353: **                     [check .../qrymod/view.c for an example] or
                    354: **                     in header files.
                    355: **             SCCS should be considered an essential tool, if only
                    356: **                     to maintain history fields.
                    357: **
                    358: **     Deficiencies:
                    359: **             It should handle pseudo tty's.
                    360: */
                    361: 
                    362: /* the following macro is defined by <sccs.h> */
                    363: SCCSID(%W%);   /* %W% is replaced by a version number by SCCS */
                    364: 
                    365: 
                    366: 
                    367: 
                    368: 
                    369: 
                    370: # define       XEQ1            5
                    371: 
                    372: struct magic
                    373: {
                    374:        char    *name;          /* name of symbol */
                    375:        int     type;           /* type of symbol, defined in symbol.h */
                    376:        int     value;          /* optional value.  This is actually
                    377:                                 * the value if it is type "integer",
                    378:                                 * a pointer to the value if it is a
                    379:                                 * string. */
                    380: };
                    381: 
                    382: struct magic   Stuff;
                    383: 
                    384: main(argc, argv)
                    385:        int argc;
                    386:        char *argv[];
                    387: {
                    388:        register struct magic *r;
                    389:        register int i;
                    390:        register int j;
                    391:        int timebuf[2];
                    392:        auto int status;
                    393: 
                    394:        /*
                    395:        ** Note that in the declarations of argc and argv above, all
                    396:        ** parameters to any function should be declared, even if they
                    397:        ** are of type int (which is the default).
                    398:        */
                    399: 
                    400:        r = &Stuff;
                    401:        /* initialize random # generator */
                    402:        time(timebuf);
                    403:        srand(timebuf[1]);
                    404: 
                    405:        /* scan Stuff structure */
                    406:        for (i = 0; i < XEQ1; i++)
                    407:        {
                    408: #              ifdef xTRACE
                    409:                if (tTf(5, 13))
                    410:                        printf("switch on type %d\n", r->reltype);
                    411: #              endif
                    412:                switch (r->type)
                    413:                {
                    414: 
                    415:                  case 0:
                    416:                  case 1:
                    417:                  case 3:
                    418:                        /* initialize */
                    419:                        printf("hi\n");
                    420:                        break;
                    421: 
                    422:                  case 2:
                    423:                        /* end of query */
                    424:                        printf("bye\n");
                    425:                        break;
                    426: 
                    427:                  default:
                    428:                        /*
                    429:                        ** be sure to print plenty of info on an error;
                    430:                        ** "syserr("bad reltype");" would not have been
                    431:                        ** sufficient.  However, don't make syserr's
                    432:                        ** overly verbose; they take much space in the
                    433:                        ** object module, and it will probably be
                    434:                        ** necessary to look at the code anyway.
                    435:                        */
                    436:                        syserr("main: bad type %d", r->type);
                    437: 
                    438:                }
                    439:        }
                    440: 
                    441:        /* resist the temptation to say "} else {" */
                    442:        if (i == 5)
                    443:        {
                    444:                i++;
                    445:                j = 4;
                    446:        }
                    447:        else
                    448:                i--;
                    449: 
                    450:        /* plot the results */
                    451:        do
                    452:        {
                    453:                i = rand() & 017;
                    454:                plot(i);
                    455:        } while (j--);
                    456: 
                    457:        /* wait for child processes to complete */
                    458:        wait(&status);
                    459:        /* end of run, print termination message and exit */
                    460:        for (i = 0; i < 2; i++)
                    461:                printf("bye ");
                    462:        printf("\n");
                    463: }
                    464: /*
                    465: **  PLOT -- Plot a Bar-Graph
                    466: **
                    467: **     Does a simple plot on a terminal -- one line's worth.
                    468: **
                    469: **     Parameters:
                    470: **             n (IN) -- number of asterisks to plot
                    471: **
                    472: **     Returns:
                    473: **             none
                    474: **
                    475: **     Side Effects:
                    476: **             none
                    477: **
                    478: **     Deficiencies:
                    479: **             Should allow scaling.
                    480: */
                    481: 
                    482: plot(n)
                    483:        int n;
                    484: {
                    485:        register int i;
                    486: 
                    487:        for (i = n; i-- > 0; )
                    488:        {
                    489:                printf("*");
                    490:        }
                    491:        printf("\n");
                    492: }

unix.superglobalmegacorp.com

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