Mercurial > hg > toybox
annotate toys/other/factor.c @ 1626:89384d54d49a draft
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
(The diff looks bigger than it is because of reindenting.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 24 Dec 2014 16:13:08 -0600 |
parents | dd336488a69b |
children | 3ac823675413 |
rev | line source |
---|---|
1410 | 1 /* factor.c - Factor integers |
2 * | |
3 * Copyright 2014 Rob Landley <rob@landley.net> | |
4 * | |
5 * No standard, but it's in coreutils | |
6 | |
7 USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN)) | |
8 | |
9 config FACTOR | |
10 bool "factor" | |
11 default y | |
12 help | |
13 usage: factor NUMBER... | |
14 | |
15 Factor integers. | |
16 */ | |
17 | |
18 #include "toys.h" | |
19 | |
20 static void factor(char *s) | |
21 { | |
22 long l, ll; | |
23 | |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
24 for (;;) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
25 while(isspace(*s)) s++; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
26 if (!*s) return; |
1410 | 27 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
28 l = strtol(s, &s, 0); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
29 if (*s && !isspace(*s)) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
30 error_msg("%s: not integer"); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
31 return; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
32 } |
1410 | 33 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
34 printf("%ld:", l); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
35 |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
36 // Negative numbers have -1 as a factor |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
37 if (l < 0) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
38 printf(" -1"); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
39 l *= -1; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
40 } |
1410 | 41 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
42 // Nothing below 4 has factors |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
43 if (l < 4) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
44 printf(" %ld\n", l); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
45 continue; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
46 } |
1410 | 47 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
48 // Special case factors of 2 |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
49 while (l && !(l&1)) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
50 printf(" 2"); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
51 l >>= 1; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
52 } |
1411
dd336488a69b
factor: catch integer overflow.
Rob Landley <rob@landley.net>
parents:
1410
diff
changeset
|
53 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
54 // test odd numbers. |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
55 for (ll=3; ;ll += 2) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
56 long lll = ll*ll; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
57 |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
58 if (lll>l || lll<ll) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
59 if (l>1) printf(" %ld", l); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
60 break; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
61 } |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
62 while (!(l%ll)) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
63 printf(" %ld", ll); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
64 l /= ll; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
65 } |
1410 | 66 } |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
67 xputc('\n'); |
1410 | 68 } |
69 } | |
70 | |
71 void factor_main(void) | |
72 { | |
73 if (toys.optc) { | |
74 char **ss; | |
75 | |
76 for (ss = toys.optargs; *ss; ss++) factor(*ss); | |
77 } else for (;;) { | |
78 char *s = 0; | |
79 size_t len = 0; | |
80 | |
81 if (-1 == getline(&s, &len, stdin)) break; | |
82 factor(s); | |
83 } | |
84 } |