blob: f85282ee1f8571f7e8e65468de33f95ff7e9f337 [file] [log] [blame]
/* --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);
}