Update action steps
[slib.git] / ndless / sbltool.c
blob785e3ec2ab3907390fbef70bc2335c4b6998d90c
1 /*
2 * sbltool.c - Executable tool of the slib, preceded by the admin project
4 * Copyright (C) 2016-2020 Zhang Maiyun
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
25 #include <slib.h>
26 #include <slib/getopt.h>
27 #include <slib/math.h>
28 #include <slib/stack.h>
30 #define INT_LEN 22
31 #define chk_fgets(s, l, f) \
32 if (!fgets((s), (l), (f))) \
33 exit(puts(""))
35 const char *ver = "4.1.0-ndless";
37 void usage(void);
39 void eio(void);
41 int ui()
43 int selection = 0;
44 char buffer[INT_LEN];
45 printf("sbltool Copyright (C) 2016-2020 Zhang Maiyun\n"
46 "This program comes with ABSOLUTELY NO WARRANTY.\n"
47 "This is free software, and you are welcome to redistribute it\n"
48 "under certain conditions; visit <https://www.gnu.org/licenses/> "
49 "for details.\n");
50 helpme:
51 printf("1: Print program version\n"
52 "2: Prime numbers in a range\n"
53 "3: Primality test\n"
54 "4: Coprime test\n"
55 "5: Greatest common factor\n"
56 "6: Lowest common multiple\n");
57 for (;;)
59 printf("(admin) ");
60 fflush(stdout);
61 chk_fgets(buffer, INT_LEN, stdin);
62 selection = strtod(buffer, NULL);
63 chk_fgets(buffer, INT_LEN, stdin);
64 if (selection == 0)
65 /* It is a character */
66 selection = buffer[0];
67 switch (selection)
69 case '\n':
70 case ' ':
71 goto helpme;
72 case 1:
73 printf("sbl admin v%s with slib v%d.%d.%d\n", ver,
74 SBLLIB_VERSION, SBLLIB_MINOR, SBLLIB_PATCHLEVEL);
75 printf("Build %s, %s\n", __DATE__, __TIME__);
76 break;
77 case 2:
79 slib_uint num1, num2;
80 printf("Minimum: ");
81 fflush(stdout);
82 chk_fgets(buffer, INT_LEN, stdin);
83 num1 = strtoslib(buffer, NULL, 0);
84 chk_fgets(buffer, INT_LEN, stdin);
85 printf("Maximum: ");
86 fflush(stdout);
87 chk_fgets(buffer, INT_LEN, stdin);
88 num2 = strtoslib(buffer, NULL, 0);
89 chk_fgets(buffer, INT_LEN, stdin);
90 slib_prtpn(num1, num2);
91 break;
93 case 3:
95 slib_uint num;
96 printf("Which number to test: ");
97 fflush(stdout);
98 chk_fgets(buffer, INT_LEN, stdin);
99 num = strtoslib(buffer, NULL, 0);
100 chk_fgets(buffer, INT_LEN, stdin);
101 if (slib_ispn(num) == 1)
102 printf("Is a prime number!\n");
103 else
104 printf("Not a prime number!\n");
105 break;
107 case 4:
109 slib_uint num1, num2;
110 printf("First number: ");
111 fflush(stdout);
112 chk_fgets(buffer, INT_LEN, stdin);
113 num1 = strtoslib(buffer, NULL, 0);
114 chk_fgets(buffer, INT_LEN, stdin);
115 printf("Second number: ");
116 fflush(stdout);
117 chk_fgets(buffer, INT_LEN, stdin);
118 num2 = strtoslib(buffer, NULL, 0);
119 chk_fgets(buffer, INT_LEN, stdin);
120 if (slib_isrp(num1, num2) == 1)
121 printf("They are coprime!\n");
122 else
123 printf("They are not coprime!\n");
124 break;
126 case 5:
128 slib_uint num1, num2;
129 printf("First number: ");
130 fflush(stdout);
131 chk_fgets(buffer, INT_LEN, stdin);
132 num1 = strtoslib(buffer, NULL, 0);
133 chk_fgets(buffer, INT_LEN, stdin);
134 printf("Second number: ");
135 fflush(stdout);
136 chk_fgets(buffer, INT_LEN, stdin);
137 num2 = strtoslib(buffer, NULL, 0);
138 chk_fgets(buffer, INT_LEN, stdin);
139 printf("gcf(%" PRIslib ", %" PRIslib ") = %" PRIslib "\n", num1,
140 num2, slib_gcf(num1, num2));
141 break;
143 case 6:
145 slib_uint num1, num2;
146 printf("First number: ");
147 fflush(stdout);
148 chk_fgets(buffer, INT_LEN, stdin);
149 num1 = strtoslib(buffer, NULL, 0);
150 chk_fgets(buffer, INT_LEN, stdin);
151 printf("Second number: ");
152 fflush(stdout);
153 chk_fgets(buffer, INT_LEN, stdin);
154 num2 = strtoslib(buffer, NULL, 0);
155 chk_fgets(buffer, INT_LEN, stdin);
156 printf("lcm(%" PRIslib ", %" PRIslib ") = %" PRIslib "\n", num1,
157 num2, slib_lcm(num1, num2));
158 break;
160 case 'q':
161 return 0;
162 case 'h':
163 goto helpme;
164 default:
165 printf("%s: Unknown option\n", buffer);
166 goto helpme;
170 int main(int argc, char *argv[])
172 int c;
173 const char *sopts = ":uhvr:g:l:p:d:c:";
174 if (argc > 1)
176 while ((c = getoptGS(argc, argv, sopts)) != -1)
178 switch (c)
180 case 'u':
181 return ui();
182 case 'h':
183 usage();
184 return 0;
185 case 'v':
186 printf("sbl admin v%s with slib v%d.%d.%d\n", ver,
187 SBLLIB_VERSION, SBLLIB_MINOR, SBLLIB_PATCHLEVEL);
188 printf("Build %s, %s\n", __DATE__, __TIME__);
189 break;
190 case 'r':
192 slib_uint n1, n2;
193 n1 = strtoslib(optargGS, NULL, 0);
194 n2 = strtoslib(argv[optindGS], NULL, 0);
195 printf("%" PRIslib " and %" PRIslib " are", n1, n2);
196 if (!slib_isrp(n1, n2))
197 printf(" not");
198 puts(" coprime");
199 break;
201 case 'g':
203 slib_uint n1, n2;
204 n1 = strtoslib(optargGS, NULL, 0);
205 n2 = strtoslib(argv[optindGS], NULL, 0);
206 printf("gcf(%" PRIslib ", %" PRIslib ") = %" PRIslib "\n",
207 n1, n2, slib_gcf(n1, n2));
208 break;
210 case 'l':
212 slib_uint n1, n2;
213 n1 = strtoslib(optargGS, NULL, 0);
214 n2 = strtoslib(argv[optindGS], NULL, 0);
215 printf("lcm(%" PRIslib ", %" PRIslib ") = %" PRIslib "\n",
216 n1, n2, slib_lcm(n1, n2));
217 break;
219 case 'p':
221 slib_uint n1, n2;
222 n1 = strtoslib(optargGS, NULL, 0);
223 n2 = strtoslib(argv[optindGS], NULL, 0);
224 slib_prtpn(n1, n2);
225 break;
227 case 'd':
229 slib_uint n;
230 n = strtoslib(optargGS, NULL, 0);
231 printf("%" PRIslib " is", n);
232 if (!slib_ispn(n))
233 printf(" not");
234 puts(" a prime number");
235 break;
237 case '?':
238 usage();
239 fprintf(stderr, "admin: unknown option -%c\n", optoptGS);
240 return 1;
241 case ':':
242 usage();
243 fprintf(stderr, "admin: option -%c needs an argument\n",
244 optoptGS);
245 return 1;
246 default:;
249 return 0;
251 else
253 return ui();
257 void usage(void)
259 printf("Usage:\n"
260 "\tadmin [-uhv] [-r <n1> <n2>] [-g <n1> <n2>] [-l <n1> <n2>]\n"
261 "\t[-p <n1> <n2>] [-d <num>] [-c <exp>]\n"
262 "Options:\n"
263 "\t-u\tInteractive mode, same as no options\n"
264 "\t-h\tShow this page.\n"
265 "\t-v\tShow version.\n"
266 "\t-r\tShow whether n1 and n2 are coprime.\n"
267 "\t-g\tGreatest common factor(divisor) of n1 and n2.\n"
268 "\t-l\tLeast common multiple of n1 and n2.\n"
269 "\t-p\tPrint prime numbers between n1 and n2.\n"
270 "\t-d\tPrimality test.\n");
272 void eio(void)
274 fprintf(stderr, "\nHmm... You've entered something I don't know!\n");
275 exit(2);