mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
352 lines
7.6 KiB
C
352 lines
7.6 KiB
C
/*
|
|
* eolstrip - strip white space from end of lines
|
|
*
|
|
* This program strips the white space from the end of every line in the
|
|
* specified program.
|
|
*
|
|
* usage: eolstrip [ -v ] [ arg ... ] files...
|
|
* -v -- verbose
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#define GETOPTARGS "vt"
|
|
|
|
char *USAGE = "\
|
|
usage: cklength [ -v ] [ arg ... ] files... \n\
|
|
-v -- verbose\n\
|
|
-t -- test only .. DO NOT OVERWRITE FILE!!!\n\
|
|
\n\
|
|
Strip the white space from the end of every line on the list of files.\n\
|
|
";
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
#include <stdarg.h>
|
|
|
|
#define BUFFER_SIZE 2048
|
|
#define MAX_PATH 2048
|
|
|
|
#define SUCCESS 0
|
|
#define FAILURE -1
|
|
#define Failed(x) (((int) (x)) == FAILURE)
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define STREQ(a,b) (strcmp(a,b) == 0)
|
|
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
|
|
/*
|
|
* Definitions for unsigned "ints"; especially for use in data structures
|
|
* that will be shared among (potentially) different cpu's (we punt on
|
|
* byte ordering problems tho)
|
|
*/
|
|
|
|
typedef unsigned char u8;
|
|
typedef unsigned short u16;
|
|
typedef unsigned long u32;
|
|
|
|
/*
|
|
* vars controlled by command line options
|
|
*/
|
|
|
|
int verbose = FALSE; /* be verbose */
|
|
int test_only = FALSE; /* test only */
|
|
|
|
extern char *optarg; /* getopt(3) control vars */
|
|
extern int optind, opterr;
|
|
extern int errno;
|
|
|
|
char *progname; /* for error() */
|
|
|
|
int process(char *arg);
|
|
void error(int errn, ...);
|
|
long getparm(char *s, long min, long max, char *msg);
|
|
|
|
#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
|
#define ERR_FATAL (ERR_ERRNO / 2) /* fatal error ; no return */
|
|
#define ERR_ABORT (ERR_ERRNO / 4) /* fatal error ; abort */
|
|
#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
|
|
|
|
#define stol(p) strtol(p, (char **) NULL, 0)
|
|
int Open(), Read(), Write();
|
|
|
|
int
|
|
main(int argc, char **argv, char **env)
|
|
{
|
|
register int c;
|
|
int showusage = FALSE; /* usage error? */
|
|
int rc = 0;
|
|
|
|
/*
|
|
* figure out invocation leaf-name
|
|
*/
|
|
|
|
if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
|
|
progname = argv[0];
|
|
else
|
|
progname++;
|
|
|
|
argv[0] = progname; /* for getopt err reporting */
|
|
|
|
/*
|
|
* Check options and arguments.
|
|
*/
|
|
|
|
opterr = 0; /* we'll report all errors */
|
|
while ((c = getopt(argc, argv, GETOPTARGS)) != EOF)
|
|
switch (c)
|
|
{
|
|
case 't': /* toggle test only mode */
|
|
test_only = ! test_only;
|
|
break;
|
|
|
|
case 'v': /* toggle verbose */
|
|
verbose = ! verbose;
|
|
break;
|
|
|
|
case '?':
|
|
showusage = TRUE;
|
|
}
|
|
|
|
if (showusage)
|
|
{
|
|
(void) fprintf(stderr, "%s", USAGE);
|
|
exit(1);
|
|
}
|
|
|
|
/*
|
|
* traverse and process the arguments
|
|
*/
|
|
|
|
for ( ; argv[optind]; optind++)
|
|
if (Failed(process(argv[optind])))
|
|
rc = FAILURE;
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* process(arg)
|
|
*/
|
|
|
|
int
|
|
process(char *arg)
|
|
{
|
|
FILE *in;
|
|
FILE *out = (FILE *) 0;
|
|
char outname[ MAX_PATH ];
|
|
char *bptr;
|
|
char buffer[ BUFFER_SIZE ];
|
|
int length;
|
|
int line_number;
|
|
int rc = SUCCESS; /* succeed by default */
|
|
|
|
in = fopen( arg, "r" );
|
|
if (!in)
|
|
error( ERR_ERRNO | ERR_FATAL, "Unable to open file (%s)\n", arg );
|
|
|
|
if ( !test_only ) {
|
|
sprintf( outname, "%s.eoltmp", arg );
|
|
|
|
out = fopen( outname, "w" );
|
|
if (!out)
|
|
error( ERR_ERRNO | ERR_FATAL, "Unable to open file (%s)\n", arg );
|
|
}
|
|
|
|
if ( verbose )
|
|
fprintf( stderr, "Processing %s\n", arg );
|
|
|
|
for ( line_number=1 ; ; line_number++ ) {
|
|
bptr = fgets( buffer, BUFFER_SIZE, in );
|
|
if (!bptr)
|
|
break;
|
|
|
|
/*
|
|
* Don't count the carriage return.
|
|
*/
|
|
|
|
length = strlen( buffer ) - 1;
|
|
|
|
if ( buffer[ length ] != '\n' )
|
|
error(ERR_ERRNO|ERR_FATAL, "Line %d too long in %s\n", line_number, arg);
|
|
|
|
while ( isspace( buffer[ length ] ) )
|
|
buffer[ length-- ] = '\0';
|
|
|
|
if ( test_only ) {
|
|
fprintf( stderr, "%s\n", arg );
|
|
break;
|
|
}
|
|
|
|
fprintf( out, "%s\n", buffer );
|
|
}
|
|
|
|
fclose( in );
|
|
if ( !test_only ) {
|
|
fclose( out );
|
|
rename( outname, arg );
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* error(errn, arglist)
|
|
* report an error to stderr using printf(3) conventions.
|
|
* Any output is preceded by '<progname>: '
|
|
*
|
|
* Uses ERR_FATAL bit to request exit(errn)
|
|
* ERR_ABORT to request abort()
|
|
* ERR_ERRNO to indicate use of errno instead of argument.
|
|
*
|
|
* If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
|
|
* associated error message is appended to the output.
|
|
*/
|
|
|
|
/*VARARGS*/
|
|
|
|
void
|
|
error(int error_flag, ...)
|
|
{
|
|
va_list arglist;
|
|
register char *format;
|
|
extern char *sys_errlist[];
|
|
extern int sys_nerr;
|
|
int local_errno;
|
|
|
|
extern int errno;
|
|
|
|
(void) fflush(stdout); /* in case stdout/stderr same */
|
|
|
|
local_errno = error_flag & ~ERR_MASK;
|
|
if (error_flag & ERR_ERRNO) /* use errno? */
|
|
local_errno = errno;
|
|
|
|
va_start(arglist, error_flag);
|
|
format = va_arg(arglist, char *);
|
|
(void) fprintf(stderr, "%s: ", progname);
|
|
(void) vfprintf(stderr, format, arglist);
|
|
va_end(arglist);
|
|
|
|
if (local_errno)
|
|
if ((local_errno > 0) && (local_errno < sys_nerr))
|
|
(void) fprintf(stderr, " (%s)\n", sys_errlist[local_errno]);
|
|
else
|
|
(void) fprintf(stderr, " (unknown errno=%d)\n", local_errno);
|
|
else
|
|
(void) fprintf(stderr, "\n");
|
|
|
|
(void) fflush(stderr);
|
|
|
|
if (error_flag & (ERR_FATAL | ERR_ABORT))
|
|
{
|
|
if (error_flag & ERR_FATAL)
|
|
{
|
|
error(0, "fatal error, exiting");
|
|
exit(local_errno ? local_errno : 1);
|
|
}
|
|
else
|
|
{
|
|
error(0, "fatal error, aborting");
|
|
abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
long
|
|
getparm(char *s,
|
|
long min,
|
|
long max,
|
|
char *msg)
|
|
{
|
|
long val;
|
|
|
|
if ( ! strchr("0123456789-", *s))
|
|
{
|
|
error(ERR_FATAL, "'%s' is not a number", s);
|
|
return min;
|
|
}
|
|
|
|
val = strtol(s, (char **) NULL, 0);
|
|
if ((val < min) || (val > max))
|
|
{
|
|
if (min == max)
|
|
error(ERR_FATAL, "%s can only be %ld", s, min);
|
|
else
|
|
error(ERR_FATAL, "%s must be between %ld and %ld", msg, min, max);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
|
|
/*
|
|
* Open()
|
|
* Perform open(2), returning the file descriptor. Prints
|
|
* error message if open fails.
|
|
*/
|
|
|
|
int
|
|
Open(char *file,
|
|
int oflag,
|
|
int mode)
|
|
{
|
|
int O_fd;
|
|
|
|
if (Failed(O_fd = open(file, oflag, mode)))
|
|
error(
|
|
ERR_ERRNO | ERR_FATAL,
|
|
"open('%s', 0x%x, 0%o) failed", file, oflag, mode
|
|
);
|
|
|
|
return O_fd;
|
|
}
|
|
|
|
/*
|
|
* Read()
|
|
* Perform read(2); prints error message if fails.
|
|
*/
|
|
|
|
int
|
|
Read(int file,
|
|
char *buffer,
|
|
unsigned int count)
|
|
{
|
|
int nbytes;
|
|
|
|
if (Failed(nbytes = read(file, buffer, count)))
|
|
error(
|
|
ERR_ERRNO | ERR_FATAL,
|
|
"read(%d, 0x%x, %d) failed", file, buffer, count
|
|
);
|
|
|
|
return nbytes;
|
|
}
|
|
|
|
/*
|
|
* Write()
|
|
* Perform write(2); prints error message if fails.
|
|
*/
|
|
|
|
int
|
|
Write(int file,
|
|
char *buffer,
|
|
unsigned int count)
|
|
{
|
|
int nbytes;
|
|
|
|
if (Failed(nbytes = write(file, buffer, count)))
|
|
error(
|
|
ERR_ERRNO | ERR_FATAL,
|
|
"write(%d, 0x%x, %d) failed", file, buffer, count
|
|
);
|
|
|
|
return nbytes;
|
|
}
|