ghscrnch.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 302 行
C
302 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
// GHSCRNCH -- utility to massage a .GH file into canonical format and to
// update the target when it differs from the generated file
//
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/utime.h>
typedef struct record record;
struct record // RECORD
{
record* _next; // - next in list
char _data[1]; // - data
};
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
static int tgt_write = FALSE; // true ==> write out target
static int have_src; // true ==> have a source record
static int have_tgt; // true ==> have a target record
static FILE* in; // input file
static FILE* tgt; // target file
static char target[1024]; // target record
static char source[1024]; // source record
static char const* src_rec; // canonical source record
static unsigned src_size; // size of source record
static record* recordsList = NULL; // list of canonical records
static record* recordsEnd; // end of list of canonical records
static void helpInfo // DUMP HELP INFORMATION
(void)
{
puts( "GHSCRNCH source target time" );
puts( " source, target, and time are files" );
puts( " target is replaced by source (in canonical format) when the" );
puts( " canonical format of the source differs from the target." );
puts( " time file has modification time set to that of source file." );
}
static void message // WRITE MESSAGE
( char const * prefix // - prefix
, char const * frag // - first fragment
, va_list frags ) // - message fragments
{
fputs( prefix, stdout );
for( ; ; ) {
if( 0 == frag ) break;
fputc( ' ', stdout );
fputs( frag, stdout );
frag = va_arg( frags, char const * );
}
fputc( '\n', stdout );
}
static void notemsg // PRINT A NOTE MESSAGE
( char const* frags // - message fragments
, ... )
{
va_list list;
va_start( list, frags );
message( "*** NOTE ***", frags, list );
va_end( list );
}
static void errmsg // PRINT AN ERROR MESSAGE
( char const* frags // - message fragments
, ... )
{
va_list list;
va_start( list, frags );
message( "*** ERROR ***", frags, list );
va_end( list );
}
static void readTgt // READ TARGET RECORD
( void )
{
if( NULL == fgets( target, sizeof( target ), tgt ) ) {
have_tgt = FALSE;
} else {
have_tgt = TRUE;
}
}
static void readSrc // READ SOURCE RECORD
( void )
{
have_src = FALSE;
while( ! have_src ) {
char const* rp;
if( NULL == fgets( source, sizeof( source ), in ) ) break;
for( rp = source; *rp == ' '; ++rp );
if( *rp != '\n' ) {
char * ep;
src_rec = rp;
ep = (char*)( rp + strlen( rp ) - 1 );
for( ; ; ) {
-- ep;
if( *ep != ' ' ) break;
}
ep[1] = '\n';
ep[2] = '\0';
src_size = ep - rp + 2;
have_src = TRUE;
break;
}
}
}
static int storeSrc // SAVE SOURCE RECORD
( void )
{
int retn;
record* rec = (record*)malloc( sizeof( record ) + src_size );
if( NULL == rec ) {
retn = FALSE;
} else {
rec->_next = NULL;
memcpy( rec->_data, src_rec, src_size + 1 );
if( NULL == recordsList ) {
recordsList = rec;
} else {
recordsEnd->_next = rec;
}
recordsEnd = rec;
retn = TRUE;
}
return retn;
}
static int setTimeFile // SET MODIFICATION TIME FOR TIME FILE
( char const * timeFile // - name of time file
, struct utimbuf const * modif ) // - modication time
{
int retn;
int try_create = TRUE;
for( ; ; ) {
if( 0 == utime( timeFile, modif ) ) {
retn = 0;
break;
}
if( try_create ) {
FILE* created = fopen( timeFile, "wt" );
try_create = FALSE;
if( 0 != created ) {
fclose( created );
continue;
}
}
errmsg( "cannot set time for"
, timeFile
, NULL );
retn = 2;
break;
}
return retn;
}
int main // MAIN-LINE
( int arg_count // - # arg.s
, char const * args[] ) // - arguments
{
int retn = 0;
if( arg_count != 4 ) {
helpInfo();
retn = 1;
} else {
in = fopen( args[1], "rt" );
if( NULL == in ) {
errmsg( "cannot open"
, args[1]
, NULL );
retn = 2;
} else {
tgt = fopen( args[2], "rt" );
if( 0 == tgt ) {
notemsg( "creating"
, args[2]
, NULL );
tgt_write = TRUE;
} else {
readTgt();
}
readSrc();
for( ; ; ) {
if( ! have_src ) break;
if( ! tgt_write ) {
if( have_tgt ) {
if( src_size == strlen( target )
&& 0 == memcmp( target, src_rec, src_size ) ) {
readTgt();
} else {
notemsg( "replacing"
, args[2]
, NULL );
tgt_write = TRUE;
}
} else {
tgt_write = TRUE;
}
}
if( ! storeSrc() ) {
errmsg( "ran out of memory", NULL );
retn = 2;
break;
}
readSrc();
}
if( have_tgt ) {
tgt_write = TRUE;
}
fclose( in );
if( NULL != tgt ) {
fclose( tgt );
}
if( 0 == retn ) {
struct stat src_stats;
struct utimbuf mod_times;
stat( args[1], &src_stats );
mod_times.actime = src_stats.st_mtime;
mod_times.modtime = src_stats.st_mtime;
if( tgt_write && retn == 0 ) {
tgt = fopen( args[2], "wt" );
if( 0 == tgt ) {
errmsg( "cannot write file"
, args[2]
, NULL );
retn = 2;
} else {
record* rec = recordsList;
while( NULL != rec ) {
if( NULL == fputs( rec->_data, tgt ) ) {
errmsg( "i/o error writing file"
, args[2]
, NULL );
retn = 2;
break;
}
rec = rec->_next;
}
fclose( tgt );
if( 0 == retn ) {
utime( args[2], &mod_times );
retn = setTimeFile( args[3], &mod_times );
}
}
} else {
retn = setTimeFile( args[3], &mod_times );
}
}
}
remove( args[1] );
}
return retn;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?