Removed a crashing bug in the options parsing. Improved the time handling.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6548 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Phipps 2004-02-10 03:42:12 +00:00
parent 02f13c4aae
commit c5cd141413

View File

@ -30,115 +30,53 @@
#include <unistd.h>
#include <OS.h>
#define UINT64_MAX (18446744073709551615LL)
const bigtime_t microsPerSecond=1000000;
static uint64 process_arg(char *fromString);
static bigtime_t process_arg(char *fromString);
static void warn_invalid(char *invalidArg);
static void suggest_help(void);
static void go_sleep(uint64 sleepTotal);
static void usage(void);
static void version(void);
char *progName;
void
go_sleep(uint64 sleepTotal)
{
snooze(sleepTotal);
}
static uint64
static bigtime_t
process_arg(char *fromString)
{
long double processed;
uint64 total;
char lastChar;
bool invalidChars = false;
bool microseconds = false;
bool milliseconds = false;
int i, length;
length = strlen(fromString);
lastChar = fromString[length - 1];
processed = atol(fromString);
if ( processed > INT_MAX )
processed = INT_MAX;
if ( processed == 0 ) {
warn_invalid(fromString);
suggest_help();
exit(1);
}
switch(lastChar) {
case 'u':
case 'U':
microseconds = true;
break;
case 'i':
case 'I':
milliseconds = true;
break;
case 's':
case 'S':
break;
case 'm':
case 'M':
processed *= 60;
break;
case 'h':
case 'H':
processed *= 3600;
break;
case 'd':
case 'D':
processed *= 86400;
break;
default: {
for (i=0; i < length; i++) {
if (! (fromString[i] >= '0' && fromString[i] <= '9'))
invalidChars = true;
}
if (invalidChars) {
warn_invalid(fromString);
suggest_help();
exit(1);
}
bigtime_t microSeconds=0;
bool endOfString=false;
int i=0;
while (i<20 && !endOfString) // Any more than 5 digits is ridiculous, but 20 is possible...
switch (fromString[i++]) {
case '0': microSeconds*=10;break;
case '1': microSeconds=10*microSeconds+1;break;
case '2': microSeconds=10*microSeconds+2;break;
case '3': microSeconds=10*microSeconds+3;break;
case '4': microSeconds=10*microSeconds+4;break;
case '5': microSeconds=10*microSeconds+5;break;
case '6': microSeconds=10*microSeconds+6;break;
case '7': microSeconds=10*microSeconds+7;break;
case '8': microSeconds=10*microSeconds+8;break;
case '9': microSeconds=10*microSeconds+9;break;
case 'u': case 'U': endOfString=true; break;
case 'i': case 'I': microSeconds*=1000; endOfString=true;break;
case 's': case 'S': case '\0': microSeconds*=microsPerSecond; endOfString=true; break;
case 'm': case 'M': microSeconds*= (60*microsPerSecond);endOfString=true; break;
case 'h': case 'H': microSeconds*= (3600*microsPerSecond);endOfString=true; break;
case 'd': case 'D': microSeconds*= (86400*microsPerSecond);endOfString=true; break;
}
}
total = (uint64) processed;
if (microseconds)
total *= 1;
else if (milliseconds)
total *= 1000;
else
total *= 1000000;
if (total > UINT64_MAX ) {
total = UINT64_MAX;
}
return(total);
if (fromString[i-1]!='\0' && fromString[i]!='\0')
warn_invalid(fromString);
return (microSeconds);
}
static void
warn_invalid(char *invalidArg)
{
fprintf(stderr, "%s: invalid time interval `%s'\n", progName, invalidArg);
}
static void
suggest_help(void)
{
fprintf(stdout, "Try `%s --help' for more information.\n", progName);
exit(1);
}
void
usage(void)
{
@ -178,53 +116,42 @@ main(int argc, char *argv[])
int argOption;
int indexptr = 0;
char * const * optargv = argv;
int i;
uint64 sleepTime = 0;
uint64 sleepTotal = 0; // in microseconds actually.
struct option helpOption = { "help", no_argument, 0, 1 } ;
struct option versionOption = { "version", no_argument, 0, 2 } ;
bigtime_t sleepTotal = 0; // in microseconds actually.
struct option options[] = {
helpOption, versionOption, {0}
{ "help", no_argument, NULL, 1 },
{ "version", no_argument, NULL, 2 },
{ NULL,0,NULL,0}
};
progName = argv[0]; // don't put this before or between structs! werrry bad things happen. ;)
progName = argv[0];
while ((argOption = getopt_long(argc, optargv, "", options, &indexptr)) != -1) {
switch (argOption) {
default:
switch (options[indexptr].val) {
case 1: // help
usage();
exit(0);
case 2: // version
version();
exit(0);
default:
suggest_help();
exit(1);
}
case 1: // help
usage();
break;
}
case 2: // version
version();
break;
default: // Should not be possible to get here!
fprintf (stderr,"HUGE problems with getopt_long!\n");
exit(1);
break;
}
exit(0);
}
if (argc - optind > 0) {
for ( i=1; i<argc; i++ ) {
if ((argv[i][0] >= '0') && (argv[i][0] <= '9')) {
sleepTime = process_arg(argv[i]);
sleepTotal += sleepTime;
} else {
if (argc - optind > 0) {
for ( int i=optind; i<argc; i++ )
if ((argv[i][0] >= '0') && (argv[i][0] <= '9'))
sleepTotal += process_arg(argv[i]);
else
warn_invalid(argv[optind]);
suggest_help();
exit(1);
}
snooze(sleepTotal);
}
go_sleep(sleepTotal);
} else {
else
usage();
}
return B_NO_ERROR;
}