home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)example.c 1.2 (ULTRIX) 2/1/85
- */
-
- # include "/usr/sys/param.h"
-
- /*
- ** DEMO PROGRAM
- **
- ** This hunk of code does virtually nothing of use. Its main
- ** purpose is to demonstrate the "official" ingres coding style.
- **
- ** This demonstrates comments. There should be a block comment
- ** at the beginning of every file and/or procedure to explain
- ** the function of the code. Important information to put here
- ** includes the parameters of the routines, any options that the
- ** user may specify, etc.
- **
- ** The first line of the comment should be a one-line description
- ** of what's going on. The remainder should be more detailed.
- ** Blank lines should seperate major points in the comments. In
- ** general, ask yourself the question, "If I didn't know what this
- ** code was, what it was for, how it fit in, etc., and if I didn't
- ** even have the documentation for it, would these comments be
- ** enough for me?"
- **
- ** Some general guidelines for the code:
- **
- ** - Commas and semicolons should always be followed by a space.
- ** Binary operators should be surrounded on both sides by
- ** spaces. Unary operators should be in direct contact
- ** with the object that they act on, except for "sizeof",
- ** which should be seperated by one space.
- **
- ** - Two statements should never go on the same line. This includes
- ** such things as an if and the associated conditionally
- ** executed statement.
- ** In cases such as this, the second half of the if
- ** should be indented one tab stop more than the if. For
- ** example, use:
- ** if (cond)
- ** statement;
- ** never:
- ** if (cond) statement;
- ** or:
- ** if (cond)
- ** statement;
- **
- ** - Braces ({}) should (almost) always be on a line by them-
- ** selves. Exceptions are closing a do, and terminating
- ** a struct definition or variable initialization. Braces
- ** should start at the same indent as the statement with
- ** which they bind, and code inside the braces should be
- ** indented one stop further. For example, use:
- ** while (cond)
- ** {
- ** code
- ** }
- ** and never:
- ** while (cond)
- ** {
- ** code
- ** }
- ** or:
- ** while (cond) {
- ** code
- ** }
- ** or:
- ** while (cond)
- ** {
- ** code
- ** }
- ** or anything else in that line. Braces which match
- ** should always be at the same tab stop.
- **
- ** - Declarations should always have at least one tab between the
- ** declaration part and the variable list part, but never
- ** any tabs within the declaration part or the variable
- ** list part. For example, in the line:
- ** register int i, j;
- ** There is a tab between the "int" and the "i", but a
- ** space between "register" and "int", since together
- ** these make up the declaration part.
- **
- ** - There should always be a space following a keyword (i.e.,
- ** for, if, do, while, switch, and return), but never
- ** between a function and the paren preceeding its
- ** arguments. For example, use:
- ** if (i == 0)
- ** exit();
- ** never:
- ** if(i == 0)
- ** exit ();
- **
- ** - Every case in a switch statement (including default) should
- ** be preceeded by a blank line. The actual word "case" or
- ** "default" should have the indent of the switch statement plus
- ** two spaces. It should be followed by a space (not a
- ** tab) and the case constant. Multiple case labels on
- ** a single block of code should be on seperate lines, but
- ** they should not be seperated by blank lines. The
- ** switch statement should in general be used in place of
- ** such constructs as:
- ** if (i == 1)
- ** code1;
- ** else
- ** if (i == 34)
- ** code2;
- ** else
- ** if (i == -1643)
- ** code3;
- ** which can be more succinctly stated as:
- ** switch (i)
- ** {
- **
- ** case 1:
- ** code1;
- ** break;
- **
- ** case 34:
- ** code2;
- ** break;
- **
- ** case -1643:
- ** code3;
- ** break;
- **
- ** }
- ** In point of fact the equivalent switch will compile
- ** extremely efficiently. (Note that if you had some
- ** instance where you could not use a case, e.g., checking
- ** for i < 5, else check for j > 3, else whatever, then
- ** the above ("if") code is in the correct style. However,
- ** an acceptable alternate structure is to consider "else if"
- ** as a primitive. Hence:
- ** if (i < 5)
- ** code1;
- ** else if (j > 3)
- ** code2;
- ** else
- ** code3;
- ** is acceptable.
- **
- ** - Do statements must always be of the form:
- ** do
- ** {
- ** code;
- ** } while (cond);
- ** even if "code" is only one line. This is done so that
- ** it is clear that the "while" is with a do, rather than
- ** a standalone "while" which is used for the side effects of
- ** evaluation of the condition.
- **
- ** - Defined constants (defined with the # define feature) must
- ** be entirely upper case. The exceptions to this are
- ** compilation flags, which begin with a lower case "x",
- ** and some sub-types for parser symbols. In any case,
- ** the majority of the symbol is upper case.
- **
- ** - Global variables should begin with an upper case letter and
- ** be otherwise all lower case. Local symbols should be
- ** entirely lower case. Procedure names are all lower
- ** case. The only exception to this is the trace routine
- ** "tTf". You should avoid user non-local symbols (globals
- ** or # define'd symbols) which are one character only;
- ** it is impossible to distinguish them.
- **
- ** - # defines and # includes should have a space after the sharp
- ** sign and be followed by a tab. In general, try to make
- ** things line up. Use:
- ** # define ARPA 25
- ** # define MAXFIELDS 18
- ** and not:
- ** #define ARPA 25
- ** #define MAXFIELDS 18
- ** Conditional compilation statements should have as many
- ** tabs as are necessary to bring the "ifdef",
- ** "ifndef", or "endif" to the tab stop of the surrounding
- ** code. The keyword ("ifdef" or "ifndef") should be
- ** followed by a space and the conditional compilation
- ** variable. Conditional compilation should be used
- ** around all trace information, timing code, and code
- ** which may vary from version to version of UNIX. See
- ** the code below for an example of conditional compila-
- ** tion use.
- **
- ** - A blank line should seperate the declarations and the code
- ** in a procedure. Blank lines should also be used freely
- ** between major subsections of your code. The major
- ** subsections should also have a comment giving some idea
- ** of what is about to occur.
- **
- ** - Use descriptive variable names, particularly for global var-
- ** iables. "IEH3462" tells me nothing; nor does "R". On
- ** the other hand, "Resultid" tells me quite a lot,
- ** including what it might be, where I might go to see
- ** how it is initialized, etc. Try not to use variables
- ** for multiple purposes.
- **
- ** - It is quite possible to name a file "printr.c" and then
- ** put the code for "destroydb" in it. Try to arrange
- ** the names of your files so that given the name of a
- ** routine, it is fairly easy to figure out which file
- ** it is in.
- **
- ** - Sometimes it is really pretty much impossible to avoid doing
- ** something which is not immediately obvious. In these
- ** cases, put in a comment telling what you are doing and
- ** why you are doing it.
- **
- ** - Try to write things that are clear, rather than things which
- ** you think are easier to compile. I mean, who really
- ** cares? For example, always declare temporary buffers
- ** as local, rather than as global. This way you can
- ** guarantee that you will never clobber the buffer in
- ** another routine accidently when it still had useful
- ** info in it.
- **
- ** Remember, it is easy to write incomprehensible code in
- ** C. If you really get off on doing this, however, go get
- ** a job programming in APL.
- **
- ** For efficiency reasons, you should always use register variables
- ** when possible. A simple and extremely effective tip is to define
- ** a register variable, and assign an oft-used parameter to it,
- ** since it is particularly inefficient to reference a parameter.
- ** Another particularly inefficient operation is referencing arrays
- ** of structures. When possible, define a register pointer to the
- ** structure, and then say:
- ** struct xyz structure[MAX];
- ** register struct xyz *p;
- ** ...
- ** for (i = 0; i < MAX; i++)
- ** {
- ** p = &structure[i];
- ** p->x = p->y + p->z;
- ** (diddle with p->???)
- ** }
- ** and not:
- ** struct xyz structure[MAX];
- ** ...
- ** for (i = 0; i < MAX; i++)
- ** {
- ** Structure[i].x = Structure[i].y + Structure[i].z;
- ** (diddle with Structure[i].???)
- ** }
- ** Remember, the nice things about register variables is that they
- ** make your code smaller and they run faster. It is hard to
- ** lose with registers. There are three restrictions which you
- ** should be aware of on register variables, however. First,
- ** The only types which may be registers are int's, char's,
- ** and pointers. Second, there may only be three register
- ** variables per subroutine. Third, you may not take the address
- ** of a register variable (i.e., you may not say "&i" if i is
- ** typed as a register variable).
- */
-
-
- # define XEQ1 5
-
- struct magic
- {
- char *name; /* name of symbol */
- int type; /* type of symbol, defined in symbol.h */
- int value; /* optional value. This is actually
- * the value if it is type "integer",
- * a pointer to the value if it is a
- * string. */
- };
-
- struct magic Stuff;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- register struct magic *r;
- register int i;
- register int j;
- int timebuf[2];
- int status;
-
- /* Note that in the declarations of argc and argv above, all
- * parameters to any function should be declared, even if they
- * are of type int (which is the default). */
-
- r = &Stuff;
- /* initialize random # generator */
- time(timebuf);
- srand(timebuf[1]);
-
- /* scan Stuff structure */
- for (i = 0; i < XEQ1; i++)
- {
- # ifdef xTRACE
- if (tTf(5, 13))
- printf("switch on type %d\n", r->reltype);
- # endif
- switch (r->type)
- {
-
- case 0:
- case 1:
- case 3:
- /* initialize */
- printf("hi\n");
- break;
-
- case 2:
- /* end of query */
- printf("bye\n");
- break;
-
- default:
- /* be sure to print plenty of info on an error;
- * "syserr("bad reltype");" would not have been
- * sufficient */
- syserr("bad type %d", r->type);
-
- }
- }
-
- /* resist the temptation to say "} else {" */
- if (i == 5)
- {
- i++;
- j = 4;
- }
- else
- i--;
-
- /* plot the results */
- do
- {
- i = rand() & 017;
- while (i--)
- {
- printf("*");
- }
- printf("\n");
- } while (j--);
-
- /* wait for child processes to complete */
- wait(&status);
- /* end of run, print termination message and exit */
- for (i = 0; i < 2; i++)
- printf("bye ");
- printf("\n");
- }