Factor updated by Chris Simmons

Sleep by Chris Simmons

New with
this version is ability to handle milliseconds and microseconds in
addition to seconds, minutes, hours, days like in standard 'sleep'.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6365 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Phil Greenway
2004-01-27 21:03:54 +00:00
parent 0202a6eb59
commit 83c60cc9e2
2 changed files with 306 additions and 80 deletions
+76 -80
View File
@@ -30,7 +30,6 @@
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <ktypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,32 +38,31 @@
static int char_to_int(char in);
static uint64 to_uint64(char *input);
static int Process(char *FromString);
static int Factor(uint64 BigNumber, uint64 FactorBy);
static int SuggestHelpMessage();
static int WarnNotValid(char *NotValidString);
static int usage(void);
static int version(void);
static int process_potential_number(char *fromString);
static int factor_number(uint64 bigNumber, uint64 factorBy);
static int suggest_help(void);
static int warn_invalid(char *fromString);
static void usage(void);
static void version(void);
#define MAX_INT_CALCULATED "18446744073709551615" // a fairly big number, 2^64 minus 1
#define MAX_TOKEN_LENGTH 20 // Hopefully we can change this upper limit in the future. ;)
char* prog_name;
bool SuggestHelp = false;
char* progName;
bool suggestHelp = false;
static int
char_to_int (char in)
char_to_int(char in)
{
if (in >= '0' && in <= '9')
return in - '0';
return(0);
}
static uint64
to_uint64 (char *input)
to_uint64(char *input)
{
uint64 output = 0;
while (*input && isdigit (*input)) {
@@ -75,7 +73,7 @@ to_uint64 (char *input)
static int
readline(char *buf, int len)
read_line(char *buf, int len)
{
int i = 0;
char ch;
@@ -108,15 +106,15 @@ readline(char *buf, int len)
static int
Process(char *FromString)
process_potential_number(char *fromString)
{
char *TestForChar;
bool FoundChar = false;
uint64 NumberToFactor;
int BaseFactor = 2;
char *testForChar;
bool foundChar = false;
uint64 numberToFactor;
int baseFactor = 2;
char str[1024];
char *Token;
const char *Tokens = " \t";
char *token;
const char *token_set = " \t";
bool factorNumber = true;
int i;
@@ -124,33 +122,33 @@ Process(char *FromString)
BString chrptr; // predefined character pointer
BString usrptr; // user submitted pointer
strcpy(str,FromString);
Token = strtok(str, Tokens);
strcpy(str,fromString);
token = strtok(str, token_set);
while (1) {
TestForChar = Token;
FoundChar = false;
testForChar = token;
foundChar = false;
while (*TestForChar) {
if (! isdigit (*TestForChar) ) {
FoundChar = true;
while (*testForChar) {
if (! isdigit (*testForChar) ) {
foundChar = true;
break;
}
*TestForChar++;
*testForChar++;
}
if (FoundChar) {
WarnNotValid(Token);
if (foundChar) {
warn_invalid(token);
} else {
if ( strlen(Token) >= MAX_TOKEN_LENGTH ) {
if ( strlen(token) >= MAX_TOKEN_LENGTH ) {
for(i=0; i < MAX_TOKEN_LENGTH; i++) {
chrptr << maxint[i];
usrptr << Token[i];
usrptr << token[i];
if ( usrptr > chrptr ) {
WarnNotValid(Token);
SuggestHelp = true;
warn_invalid(token);
suggestHelp = true;
factorNumber = false;
break;
@@ -159,16 +157,16 @@ Process(char *FromString)
}
if ( factorNumber ) {
NumberToFactor = to_uint64(Token);
(void)fprintf(stdout, "%Lu:", NumberToFactor);
Factor(NumberToFactor, BaseFactor);
(void)printf("\n");
numberToFactor = to_uint64(token);
fprintf(stdout, "%Lu:", numberToFactor);
factor_number(numberToFactor, baseFactor);
fprintf(stdout, "\n");
}
}
Token = strtok(NULL, Tokens);
token = strtok(NULL, token_set);
if (Token == NULL)
if (token == NULL)
break;
}
@@ -177,75 +175,73 @@ Process(char *FromString)
static int
Factor(uint64 BigNumber, uint64 FactorBy)
factor_number(uint64 bigNumber, uint64 factorBy)
{
if ( ( BigNumber == 1 ) || ( BigNumber == 0 ) ) {
if ( BigNumber == 1 )
(void)fprintf(stdout, " %d", 1);
if ( ( bigNumber == 1 ) || ( bigNumber == 0 ) ) {
if ( bigNumber == 1 )
fprintf(stdout, " %d", 1);
return(0);
}
uint64 RootNumber = (uint64)sqrt(BigNumber) + 1 ;
uint64 rootNumber = (uint64)sqrt(bigNumber) + 1 ;
while ( FactorBy <= RootNumber ) {
if ( (BigNumber % FactorBy) == 0 ) {
(void)fprintf(stdout, " %Lu", FactorBy);
while ( factorBy <= rootNumber ) {
if ( (bigNumber % factorBy) == 0 ) {
fprintf(stdout, " %Lu", factorBy);
break;
}
FactorBy++;
factorBy++;
}
if ( FactorBy > RootNumber ) {
(void)fprintf(stdout, " %Lu", BigNumber);
if ( factorBy > rootNumber ) {
fprintf(stdout, " %Lu", bigNumber);
return(0);
}
Factor(BigNumber/FactorBy, FactorBy);
factor_number(bigNumber/factorBy, factorBy);
return(0);
}
static int
SuggestHelpMessage()
suggest_help()
{
(void)fprintf(stdout, "Try `%s --help' for more information.\n", prog_name);
fprintf(stderr, "Try `%s --help' for more information.\n", progName);
return(0);
}
static int
WarnNotValid(char *NotValidString)
warn_invalid(char *fromString)
{
(void)fprintf(stdout, "%s: `%s' is not a valid positive integer\n", prog_name, NotValidString);
fprintf(stderr, "%s: `%s' is not a valid positive integer\n", progName, fromString);
return(0);
}
static int
static void
usage(void)
{
(void)fprintf(stdout, "factor OBOS (http://www.openbeos.org/)
(void)fprintf(stdout, "%s OBOS (http://www.openbeos.org/)
Usage: %s [NUMBER]...
or: %s OPTION
--help\t\tdisplay this help and exit
--version\tdisplay version information and exit
--help display this help and exit
--version output version information and exit
Print the prime factors of all specified positive integer NUMBERs.
If no NUMBERS are specified on the command line, they are read from standard input.
You may use a delimiter characters such as space and tab to separate NUMBERS.
", prog_name, prog_name );
return(0);
", progName, progName, progName );
}
static int
static void
version(void)
{
(void)fprintf(stdout, "%s OBOS (http://www.openbeos.org/)\n", prog_name);
return(0);
fprintf(stdout, "%s OBOS (http://www.openbeos.org/)\n", progName);
}
@@ -255,34 +251,34 @@ main(int argc, char *argv[])
int argOption;
int indexptr = 0;
char * const * optargv = argv;
bool Processed = false;
bool processed = false;
int i;
char buf[1024];
prog_name = argv[0];
progName = argv[0];
struct option help_opt = { "help", no_argument, 0, 1 } ;
struct option version_opt = { "version", no_argument, 0, 2 } ;
struct option helpOption = { "help", no_argument, 0, 1 } ;
struct option versionOption = { "version", no_argument, 0, 2 } ;
struct option options[] = {
help_opt, version_opt, 0
helpOption, versionOption, {0}
};
for ( i=1; i<argc; i++ ) {
if ((argv[i][0] >= '0') && (argv[i][0] <= '9')) {
Processed = true;
Process(argv[i]);
processed = true;
process_potential_number(argv[i]);
} else {
if ( ( argv[i][0] == '-' ) && (argv[i][1] >= '0') && (argv[i][1] <= '9') ) {
Processed = true;
WarnNotValid(argv[i]);
SuggestHelp = true;
processed = true;
warn_invalid(argv[i]);
suggestHelp = true;
}
}
}
if ( SuggestHelp == true ) {
SuggestHelpMessage();
if ( suggestHelp == true ) {
suggest_help();
exit(0);
}
@@ -305,14 +301,14 @@ main(int argc, char *argv[])
argc -= optind;
if ( (argc == 0) || (Processed == false) ) {
if ( (argc == 0) || (processed == false) ) {
// read stdin
for (;;) {
int chars_read;
chars_read = readline(buf, sizeof(buf));
chars_read = read_line(buf, sizeof(buf));
if (chars_read > 0)
Process(buf);
process_potential_number(buf);
}
}
return B_NO_ERROR;
+230
View File
@@ -0,0 +1,230 @@
/*
** Copyright (c) 2004 OBOS
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <OS.h>
#define UINT64_MAX (18446744073709551615LL)
static uint64 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
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);
}
}
}
total = (uint64) processed;
if (microseconds)
total *= 1;
else if (milliseconds)
total *= 1000;
else
total *= 1000000;
if (total > UINT64_MAX ) {
total = UINT64_MAX;
}
return(total);
}
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);
}
void
usage(void)
{
fprintf(stderr,
"%s OBOS (http://www.openbeos.org/)
Usage: %s [OPTION]... NUMBER[SUFFIX]
SUFFIX may be:
u microseconds
i milliseconds
s seconds (default if no SUFFIX given)
m minutes
h hours
d days
--help display this help and exit
--version output version information and exit
Pause for NUMBER seconds.
", progName, progName );
}
void
version(void)
{
fprintf(stderr, "%s OBOS (http://www.openbeos.org/)\n", progName);
}
int
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 } ;
struct option options[] = {
helpOption, versionOption, {0}
};
progName = argv[0]; // don't put this before or between structs! werrry bad things happen. ;)
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);
}
break;
}
}
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 {
warn_invalid(argv[optind]);
suggest_help();
exit(1);
}
}
go_sleep(sleepTotal);
} else {
usage();
}
return B_NO_ERROR;
}