|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.