Mercurial > hg > toybox
annotate toys/other/factor.c @ 1736:5892daac85ab draft
Switch nsenter to default y.
author | Rob Landley <rob@landley.net> |
---|---|
date | Thu, 12 Mar 2015 15:34:03 -0500 |
parents | 3ac823675413 |
children |
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 (;;) { |
1718
3ac823675413
Fix several printf_format warnings.
Rob Landley <rob@landley.net>
parents:
1626
diff
changeset
|
25 char *err = s; |
3ac823675413
Fix several printf_format warnings.
Rob Landley <rob@landley.net>
parents:
1626
diff
changeset
|
26 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
27 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
|
28 if (!*s) return; |
1410 | 29 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
30 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
|
31 if (*s && !isspace(*s)) { |
1718
3ac823675413
Fix several printf_format warnings.
Rob Landley <rob@landley.net>
parents:
1626
diff
changeset
|
32 error_msg("%s: not integer", err); |
3ac823675413
Fix several printf_format warnings.
Rob Landley <rob@landley.net>
parents:
1626
diff
changeset
|
33 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
34 return; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
35 } |
1410 | 36 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
37 printf("%ld:", l); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
38 |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
39 // 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
|
40 if (l < 0) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
41 printf(" -1"); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
42 l *= -1; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
43 } |
1410 | 44 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
45 // 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
|
46 if (l < 4) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
47 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
|
48 continue; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
49 } |
1410 | 50 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
51 // 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
|
52 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
|
53 printf(" 2"); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
54 l >>= 1; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
55 } |
1411
dd336488a69b
factor: catch integer overflow.
Rob Landley <rob@landley.net>
parents:
1410
diff
changeset
|
56 |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
57 // test odd numbers. |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
58 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
|
59 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
|
60 |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
61 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
|
62 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
|
63 break; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
64 } |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
65 while (!(l%ll)) { |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
66 printf(" %ld", ll); |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
67 l /= ll; |
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
68 } |
1410 | 69 } |
1626
89384d54d49a
Teach factor to accept whitespace separated arguments (reported by Robert Thompson).
Rob Landley <rob@landley.net>
parents:
1411
diff
changeset
|
70 xputc('\n'); |
1410 | 71 } |
72 } | |
73 | |
74 void factor_main(void) | |
75 { | |
76 if (toys.optc) { | |
77 char **ss; | |
78 | |
79 for (ss = toys.optargs; *ss; ss++) factor(*ss); | |
80 } else for (;;) { | |
81 char *s = 0; | |
82 size_t len = 0; | |
83 | |
84 if (-1 == getline(&s, &len, stdin)) break; | |
85 factor(s); | |
86 } | |
87 } |