C11 improvements and factor
authorErkin Alp Güney <erkinalp9035@gmail.com>
Sun, 8 Mar 2015 15:38:25 +0000 (17:38 +0200)
committerErkin Alp Güney <erkinalp9035@gmail.com>
Sun, 8 Mar 2015 16:22:23 +0000 (18:22 +0200)
C11: gets_s() added
prime factorisation utility added

Applications/util/factor.c [new file with mode: 0644]
Library/libs/gets.c

diff --git a/Applications/util/factor.c b/Applications/util/factor.c
new file mode 100644 (file)
index 0000000..570270e
--- /dev/null
@@ -0,0 +1,87 @@
+/* factor.c - Factor integers
+ *
+ * Copyright 2014 Rob Landley <rob@landley.net>
+ *
+ * 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 || lll<ll) {
+        if (l>1) 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);
+  }
+}
index eb118f7..52308e6 100644 (file)
@@ -9,23 +9,34 @@
 #include "stdio-l.h"\r
 \r
 char *gets(char *str) /* BAD function; DON'T use it! */ \r
-{
+{\r
        /* Auwlright it will work but of course _your_ program will crash */ \r
        /* if it's given a too long line */ \r
-       register int c;
-       register char *p = str;
+       register int c;\r
+       register char *p = str;\r
+\r
+       while (((c = getc(stdin)) != EOF) && (c != '\n'))\r
+               *p++ = c;\r
+       *p = '\0';\r
+       return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */\r
+}\r
+\r
+char *gets_s(char *str,size_t maxlen)\r
+{\r
+       register int c;\r
+       register char *p=str;\r
+\r
+       while ( (((c = getc(stdin)) != EOF) && (c != '\n')) && ( p - str < maxlen) )\r
+               *p++=c;\r
+       *p='\0';\r
+       return (((c == EOF) && (p == str)) ? NULL : str);/* NULL == EOF */\r
+}\r
 \r
-       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) \r
-{
-       register int n;
+{\r
+       register int n;\r
        if (((n = fputs(str, stdout)) == EOF) \r
-              ||(putc('\n', stdout) == EOF))
-               return (EOF);
-       return (++n);
-}
+              ||(putc('\n', stdout) == EOF))\r
+               return (EOF);\r
+       return (++n);\r
+}\r