home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / INGRES.ZIP / INGRES.C
Encoding:
C/C++ Source or Header  |  1987-03-18  |  10.8 KB  |  350 lines

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