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