| /* --COPYRIGHT--,EPL |
| *Copyright (c) 2008 Texas Instruments and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Texas Instruments - initial implementation |
| * |
| * --/COPYRIGHT--*/ |
| /* |
| * ======== vers.c ======== |
| * Extract version information from files. |
| * |
| * Version information is assumed to be a string (i.e., a NULL |
| * terminated secuence of printable characters) that begins with the |
| * sequence "@(#)". |
| * |
| *! Revision History |
| *! ================ |
| *! 17-Jan-2006 sasa updated per new RTSC types and headers |
| */ |
| |
| #include <xdc/std.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #ifdef xdc_target__os_Windows |
| #include <fcntl.h> |
| #include <io.h> |
| #endif |
| |
| static Int ch; |
| static Int nullFlag; |
| static FILE *inFile; |
| static String *fileList; |
| static String versName; |
| |
| static Void nextCh(Void); |
| static Void nextFile(Void); |
| static Int skipNull(Int nbytes); |
| |
| #define MAXNULL 3 |
| |
| /* |
| * ======== main ======== |
| */ |
| |
| Int main( Int argc, String argv[] ) |
| { |
| Int state; |
| |
| versName = argv[0]; |
| fileList = ++argv; |
| |
| #ifdef xdc_target__os_Windows |
| setmode(fileno(stdin), O_BINARY); |
| #endif |
| |
| if (argc == 1) { |
| inFile = stdin; |
| } |
| else { |
| nextFile(); |
| } |
| |
| /* infinite loop - nextCh() will exit() */ |
| for (state = 0;;) { |
| |
| switch (state) { |
| |
| /* initial state */ |
| case 0 : { |
| state = (ch == '@') ? 1 : 0; |
| nextCh(); |
| break; |
| } |
| |
| /* previous character was a '@' */ |
| case 1 : { |
| nullFlag = skipNull(MAXNULL); |
| if (ch == '(') { |
| nextCh(); |
| state = 2; /* proceed to next state */ |
| } |
| else { |
| state = 0; /* return to initial state */ |
| } |
| break; |
| } |
| |
| /* previous two characters we "@(" */ |
| case 2 : { |
| nullFlag = skipNull(MAXNULL); |
| if (ch == '#') { |
| nextCh(); |
| state = 3; /* proceed to next state */ |
| } |
| else { |
| state = 0; /* return to initial state */ |
| } |
| break; |
| } |
| |
| /* previous three characters we "@(#" */ |
| case 3 : { |
| nullFlag = skipNull(MAXNULL); |
| if (ch == ')') { |
| nextCh(); |
| putchar('\t'); |
| state = 4; /* proceed to next state */ |
| } |
| else { |
| state = 0; /* return to initial state */ |
| } |
| break; |
| } |
| |
| /* previous four characters were "@(#)", print version string! */ |
| case 4 : { |
| if (nullFlag) { |
| skipNull(nullFlag); |
| } |
| |
| /* if we reach the end of the version string return |
| * to the initial state. |
| */ |
| if (ch == '\000' || ch == '\n' || ch == '"') { |
| putchar('\n'); |
| state = 0; /* return to initial state */ |
| nextCh(); |
| break; |
| } |
| |
| /* Otherwise, output next character in version string |
| * and stay in this state. |
| */ |
| putchar(ch); |
| nextCh(); |
| break; |
| } |
| |
| /* we should never get here! */ |
| default : { |
| fprintf(stderr, "%s: internal error (state %d)\n", versName, state); |
| return(1); |
| break; |
| } |
| } |
| } |
| /*NOTREACHED*/ |
| } |
| |
| /* |
| * ======== nextCh ======== |
| */ |
| static Void nextCh(Void) |
| { |
| if ( (ch = getc(inFile)) == EOF ) { |
| |
| /* Close the current file and open next file (if there is any) */ |
| if (fclose(inFile) != 0) { |
| fprintf(stderr, "Can't close %s\n", *fileList); |
| } |
| |
| nextFile(); |
| } |
| } |
| |
| |
| /* |
| * ======== nextFile ======== |
| */ |
| static Void nextFile(Void) |
| { |
| if (*fileList == NULL) { |
| exit(0); |
| } |
| |
| if ((inFile = fopen(*fileList, "rb")) == NULL) { |
| fprintf(stderr, "%s: can't open %s\n", versName, *fileList); |
| exit(1); |
| } |
| |
| printf("%s:\n", *fileList++); |
| } |
| |
| |
| /* |
| * ======== skipNull ======== |
| */ |
| static Int skipNull(Int nbytes) |
| { |
| Int i; |
| |
| for (i = 0; i < nbytes; i++) { |
| if (ch != '\000') { |
| return (i); |
| } |
| nextCh(); |
| } |
| |
| return (ch != '\000' ? i : 0); |
| } |