[BACK]Return to gencat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / gencat

Annotation of src/usr.bin/gencat/gencat.c, Revision 1.1

1.1     ! deraadt     1:
        !             2: /***********************************************************
        !             3: Copyright 1990, by Alfalfa Software Incorporated, Cambridge, Massachusetts.
        !             4:
        !             5:                         All Rights Reserved
        !             6:
        !             7: Permission to use, copy, modify, and distribute this software and its
        !             8: documentation for any purpose and without fee is hereby granted,
        !             9: provided that the above copyright notice appear in all copies and that
        !            10: both that copyright notice and this permission notice appear in
        !            11: supporting documentation, and that Alfalfa's name not be used in
        !            12: advertising or publicity pertaining to distribution of the software
        !            13: without specific, written prior permission.
        !            14:
        !            15: ALPHALPHA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            17: ALPHALPHA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            21: SOFTWARE.
        !            22:
        !            23: If you make any modifications, bugfixes or other changes to this software
        !            24: we'd appreciate it if you could send a copy to us so we can keep things
        !            25: up-to-date.  Many thanks.
        !            26:                                Kee Hinckley
        !            27:                                Alfalfa Software, Inc.
        !            28:                                267 Allston St., #3
        !            29:                                Cambridge, MA 02139  USA
        !            30:                                nazgul@alfalfa.com
        !            31:
        !            32: ******************************************************************/
        !            33:
        !            34: /* Edit History
        !            35:
        !            36: 01/18/91   3 hamilton  #if not reparsed
        !            37: 01/12/91   2 schulert  conditionally use prototypes
        !            38: 12/23/90   2 hamilton  Fix fd == NULL to fd < 0
        !            39: 11/03/90   1 hamilton  Alphalpha->Alfalfa & OmegaMail->Poste
        !            40: 08/13/90   1 schulert  move from ua to omu
        !            41: */
        !            42:
        !            43: #include <stdio.h>
        !            44: #include <sys/types.h>
        !            45: #ifdef SYSV
        !            46: #include <sys/fcntl.h>
        !            47: #define L_SET SEEK_SET
        !            48: #define L_INCR SEEK_CUR
        !            49: #endif
        !            50: #include <sys/file.h>
        !            51: #include <sys/stat.h>
        !            52: #include "gencat.h"
        !            53:
        !            54: /*
        !            55:  * The spec says the syntax is "gencat catfile msgfile...".
        !            56:  * We extend it to:
        !            57:  *     gencat [-lang C|C++|ANSIC] catfile msgfile [-h <header-file>]...
        !            58:  * Flags are order dependant, we'll take whatever lang was most recently chosen
        !            59:  * and use it to generate the next header file.  The header files are generated
        !            60:  * at the point in the command line they are listed.  Thus the sequence:
        !            61:  *     gencat -lang C foo.cat foo.mcs -h foo.h -lang C++ bar.mcs -h bar.H
        !            62:  * will put constants from foo.mcs into foo.h and constants from bar.mcs into
        !            63:  * bar.h.  Constants are not saved in the catalog file, so nothing will come
        !            64:  * from that, even if things have been defined before.  The constants in foo.h
        !            65:  * will be in C syntax, in bar.H in C++ syntax.
        !            66:  */
        !            67:
        !            68: #if ANSI_C || defined(__cplusplus)
        !            69: # define P_(x) x
        !            70: #else
        !            71: # define P_(x) /**/
        !            72: #endif
        !            73:
        !            74: static void writeIfChanged P_((char *fname, int lang, int orConsts));
        !            75:
        !            76: #undef P_
        !            77:
        !            78: void usage() {
        !            79:     fprintf(stderr, "Use: gencat [-new] [-or] [-lang C|C++|ANSIC]\n");
        !            80:     fprintf(stderr, "            catfile msgfile [-h <header-file>]...\n");
        !            81: }
        !            82:
        !            83: void main(
        !            84: #if ANSI_C || defined(__cplusplus)
        !            85:                int argc, char *argv[])
        !            86: #else
        !            87:                argc, argv)
        !            88: int argc;
        !            89: char *argv[];
        !            90: #endif
        !            91: {
        !            92:     int                ofd, ifd, i;
        !            93:     FILE       *fptr;
        !            94:     char       *catfile = NULL;
        !            95:     char       *input = NULL;
        !            96:     int                lang = MCLangC;
        !            97:     int                new = False;
        !            98:     int                orConsts = False;
        !            99:
        !           100:     for (i = 1; i < argc; ++i) {
        !           101:        if (argv[i][0] == '-') {
        !           102:            if (strcmp(argv[i], "-lang") == 0) {
        !           103:                ++i;
        !           104:                if (strcmp(argv[i], "C") == 0) lang = MCLangC;
        !           105:                else if (strcmp(argv[i], "C++") == 0) lang = MCLangCPlusPlus;
        !           106:                else if (strcmp(argv[i], "ANSIC") == 0) lang = MCLangANSIC;
        !           107:                else {
        !           108:                    fprintf(stderr, "gencat: Unrecognized language: %s\n", argv[i]);
        !           109:                    exit(1);
        !           110:                }
        !           111:            } else if (strcmp(argv[i], "-h") == 0) {
        !           112:                if (!input) {
        !           113:                    fprintf(stderr, "gencat: Can't write to a header before reading something.\n");
        !           114:                    exit(1);
        !           115:                }
        !           116:                ++i;
        !           117:                writeIfChanged(argv[i], lang, orConsts);
        !           118:            } else if (strcmp(argv[i], "-new") == 0) {
        !           119:                if (catfile) {
        !           120:                    fprintf(stderr, "gencat: You must specify -new before the catalog file name\n");
        !           121:                    exit(1);
        !           122:                }
        !           123:                new = True;
        !           124:            } else if (strcmp(argv[i], "-or") == 0) {
        !           125:                orConsts = ~orConsts;
        !           126:            } else {
        !           127:                usage();
        !           128:                exit(1);
        !           129:            }
        !           130:         } else {
        !           131:            if (!catfile) {
        !           132:                catfile = argv[i];
        !           133:                if (new) {
        !           134:                    if ((ofd = open(catfile, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
        !           135:                        fprintf(stderr, "gencat: Unable to create a new %s.\n", catfile);
        !           136:                        exit(1);
        !           137:                    }
        !           138:                } else if ((ofd = open(catfile, O_RDONLY)) < 0) {
        !           139:                    if ((ofd = open(catfile, O_WRONLY|O_CREAT, 0666)) < 0) {
        !           140:                        fprintf(stderr, "gencat: Unable to create %s.\n", catfile);
        !           141:                        exit(1);
        !           142:                    }
        !           143:                } else {
        !           144:                    MCReadCat(ofd);
        !           145:                    close(ofd);
        !           146:                    if ((ofd = open(catfile, O_WRONLY|O_TRUNC)) < 0) {
        !           147:                        fprintf(stderr, "gencat: Unable to truncate %s.\n", catfile);
        !           148:                        exit(1);
        !           149:                    }
        !           150:                }
        !           151:            } else {
        !           152:                input = argv[i];
        !           153:                if ((ifd = open(input, O_RDONLY)) < 0) {
        !           154:                    fprintf(stderr, "gencat: Unable to read %s\n", input);
        !           155:                    exit(1);
        !           156:                }
        !           157:                MCParse(ifd);
        !           158:                close(ifd);
        !           159:            }
        !           160:        }
        !           161:     }
        !           162:     if (catfile) {
        !           163:        MCWriteCat(ofd);
        !           164:        exit(0);
        !           165:     } else {
        !           166:        usage();
        !           167:        exit(1);
        !           168:     }
        !           169: }
        !           170:
        !           171: static void writeIfChanged(
        !           172: #if ANSI_C || defined(__cplusplus)
        !           173:                char *fname, int lang, int orConsts)
        !           174: #else
        !           175:                fname, lang, orConsts)
        !           176: char *fname;
        !           177: int lang;
        !           178: int orConsts;
        !           179: #endif
        !           180: {
        !           181:     char       tmpname[32];
        !           182:     char       buf[BUFSIZ], tbuf[BUFSIZ], *cptr, *tptr;
        !           183:     int                fd, tfd;
        !           184:     int                diff = False;
        !           185:     int                c, len, tlen;
        !           186:     struct stat        sbuf;
        !           187:
        !           188:     /* If it doesn't exist, just create it */
        !           189:     if (stat(fname, &sbuf)) {
        !           190:        if ((fd = open(fname, O_WRONLY|O_CREAT, 0666)) < 0) {
        !           191:            fprintf(stderr, "gencat: Unable to create header file %s.\n", fname);
        !           192:            exit(1);
        !           193:        }
        !           194:        MCWriteConst(fd, lang, orConsts);
        !           195:        close(fd);
        !           196:        return;
        !           197:     }
        !           198:
        !           199:     /* If it does exist, create a temp file for now */
        !           200:     sprintf(tmpname, "/tmp/gencat.%d", (int) getpid());
        !           201:     if ((tfd = open(tmpname, O_RDWR|O_CREAT, 0666)) < 0) {
        !           202:        fprintf(stderr, "gencat: Unable to open temporary file: %s\n", tmpname);
        !           203:        exit(1);
        !           204:     }
        !           205:     unlink(tmpname);
        !           206:
        !           207:     /* Write to the temp file and rewind */
        !           208:     MCWriteConst(tfd, lang, orConsts);
        !           209:
        !           210:     /* Open the real header file */
        !           211:     if ((fd = open(fname, O_RDONLY)) < 0) {
        !           212:        fprintf(stderr, "gencat: Unable to read header file: %s\n", fname);
        !           213:        exit(1);
        !           214:     }
        !           215:
        !           216:     /* Backup to the start of the temp file */
        !           217:     if (lseek(tfd, 0L, L_SET) < 0) {
        !           218:        fprintf(stderr, "gencat: Unable to seek in tempfile: %s\n", tmpname);
        !           219:        exit(1);
        !           220:     }
        !           221:
        !           222:     /* Now compare them */
        !           223:     while ((tlen = read(tfd, tbuf, BUFSIZ)) > 0) {
        !           224:        if ((len = read(fd, buf, BUFSIZ)) != tlen) {
        !           225:            diff = True;
        !           226:            goto done;
        !           227:        }
        !           228:        for (cptr = buf, tptr = tbuf; cptr < buf+len; ++cptr, ++tptr) {
        !           229:            if (*tptr != *cptr) {
        !           230:                diff = True;
        !           231:                goto done;
        !           232:            }
        !           233:        }
        !           234:     }
        !           235: done:
        !           236:     if (diff) {
        !           237:        if (lseek(tfd, 0L, L_SET) < 0) {
        !           238:            fprintf(stderr, "gencat: Unable to seek in tempfile: %s\n", tmpname);
        !           239:            exit(1);
        !           240:        }
        !           241:        close(fd);
        !           242:        if ((fd = open(fname, O_WRONLY|O_TRUNC)) < 0) {
        !           243:            fprintf(stderr, "gencat: Unable to truncate header file: %s\n", fname);
        !           244:            exit(1);
        !           245:        }
        !           246:        while ((len = read(tfd, buf, BUFSIZ)) > 0) {
        !           247:            if (write(fd, buf, len) != len) {
        !           248:                fprintf(stderr, "gencat: Error writing to header file: %s\n", fname);
        !           249:            }
        !           250:        }
        !           251:     }
        !           252:     close(fd);
        !           253:     close(tfd);
        !           254: }