From: Erkin Alp Güney Date: Sun, 8 Mar 2015 15:38:25 +0000 (+0200) Subject: C11 improvements and factor X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=825923e616eb71f3ad187b47e6a6f7344190cec0;p=FUZIX.git C11 improvements and factor C11: gets_s() added prime factorisation utility added --- diff --git a/Applications/util/factor.c b/Applications/util/factor.c new file mode 100644 index 00000000..570270ed --- /dev/null +++ b/Applications/util/factor.c @@ -0,0 +1,87 @@ +/* factor.c - Factor integers + * + * Copyright 2014 Rob Landley + * + * No standard, but it's in coreutils + +USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN)) + +config FACTOR + bool "factor" + default y + help + usage: factor NUMBER... + + Factor integers. +*/ + +#include "toys.h" + +static void factor(char *s) +{ + long l, ll; + + for (;;) { + char *err = s; + + while(isspace(*s)) s++; + if (!*s) return; + + l = strtol(s, &s, 0); + if (*s && !isspace(*s)) { + error_msg("%s: not integer", err); + + return; + } + + printf("%ld:", l); + + // Negative numbers have -1 as a factor + if (l < 0) { + printf(" -1"); + l *= -1; + } + + // Nothing below 4 has factors + if (l < 4) { + printf(" %ld\n", l); + continue; + } + + // Special case factors of 2 + while (l && !(l&1)) { + printf(" 2"); + l >>= 1; + } + + // test odd numbers. + for (ll=3; ;ll += 2) { + long lll = ll*ll; + + if (lll>l || lll1) printf(" %ld", l); + break; + } + while (!(l%ll)) { + printf(" %ld", ll); + l /= ll; + } + } + xputc('\n'); + } +} + +void factor_main(void) +{ + if (toys.optc) { + char **ss; + + for (ss = toys.optargs; *ss; ss++) factor(*ss); + } else for (;;) { + char *s = 0; + size_t len = 0; + + if (-1 == getline(&s, &len, stdin)) break; + factor(s); + } +} diff --git a/Library/libs/gets.c b/Library/libs/gets.c index eb118f76..52308e60 100644 --- a/Library/libs/gets.c +++ b/Library/libs/gets.c @@ -9,23 +9,34 @@ #include "stdio-l.h" char *gets(char *str) /* BAD function; DON'T use it! */ -{ +{ /* Auwlright it will work but of course _your_ program will crash */ /* if it's given a too long line */ - register int c; - register char *p = str; + register int c; + register char *p = str; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */ +} + +char *gets_s(char *str,size_t maxlen) +{ + register int c; + register char *p=str; + + while ( (((c = getc(stdin)) != EOF) && (c != '\n')) && ( p - str < maxlen) ) + *p++=c; + *p='\0'; + return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */ +} - while (((c = getc(stdin)) != EOF) && (c != '\n')) - *p++ = c; - *p = '\0'; - return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */ -} - int puts(const void *str) -{ - register int n; +{ + register int n; if (((n = fputs(str, stdout)) == EOF) - ||(putc('\n', stdout) == EOF)) - return (EOF); - return (++n); -} + ||(putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +}