diff options
| author | David M. Syzdek <david@syzdek.net> | 2021-10-11 16:45:35 -0800 |
|---|---|---|
| committer | David M. Syzdek <david@syzdek.net> | 2021-10-11 16:46:08 -0800 |
| commit | 73c87001ad1130f30c20f72bec0cc00c5098d624 (patch) | |
| tree | e2cd0a4ca2ecaef04432323c21a1e976d3de7185 /src | |
| parent | 3af74ad228bcdf324581e439a240721ca59a945b (diff) | |
| download | dmstools-73c87001ad1130f30c20f72bec0cc00c5098d624.tar.gz dmstools-73c87001ad1130f30c20f72bec0cc00c5098d624.tar.bz2 dmstools-73c87001ad1130f30c20f72bec0cc00c5098d624.tar.xz dmstools-73c87001ad1130f30c20f72bec0cc00c5098d624.zip | |
numconvert: adding ability to specify order of output
Diffstat (limited to 'src')
| -rw-r--r-- | src/numconvert.c | 147 |
1 files changed, 95 insertions, 52 deletions
diff --git a/src/numconvert.c b/src/numconvert.c index ff90a08..1f94699 100644 --- a/src/numconvert.c +++ b/src/numconvert.c | |||
| @@ -113,7 +113,7 @@ | |||
| 113 | int main(int argc, char * argv[]); | 113 | int main(int argc, char * argv[]); |
| 114 | 114 | ||
| 115 | // print value | 115 | // print value |
| 116 | void my_print(int32_t opt, uintmax_t byte); | 116 | void my_print(int32_t opt, uintmax_t byte, const char * order); |
| 117 | 117 | ||
| 118 | //displays usage information | 118 | //displays usage information |
| 119 | void my_usage(void); | 119 | void my_usage(void); |
| @@ -133,18 +133,19 @@ void my_version(void); | |||
| 133 | /// @param[in] argv array of arguments | 133 | /// @param[in] argv array of arguments |
| 134 | int main(int argc, char * argv[]) | 134 | int main(int argc, char * argv[]) |
| 135 | { | 135 | { |
| 136 | int c; | 136 | int c; |
| 137 | int base; | 137 | int base; |
| 138 | int optbase; | 138 | int optbase; |
| 139 | int opt_index; | 139 | int opt_index; |
| 140 | int32_t opt; | 140 | int32_t opt; |
| 141 | intmax_t x; | 141 | intmax_t x; |
| 142 | intmax_t y; | 142 | intmax_t y; |
| 143 | uintmax_t num; | 143 | uintmax_t num; |
| 144 | char * endptr; | 144 | char * endptr; |
| 145 | const char * order; | ||
| 145 | 146 | ||
| 146 | // getopt options | 147 | // getopt options |
| 147 | static char short_opt[] = "AaBbDdhlOoRrsVXx"; | 148 | static char short_opt[] = "AaBbDdf:hlOoRrsVXx"; |
| 148 | static struct option long_opt[] = | 149 | static struct option long_opt[] = |
| 149 | { | 150 | { |
| 150 | {"help", no_argument, 0, 'h'}, | 151 | {"help", no_argument, 0, 'h'}, |
| @@ -154,6 +155,7 @@ int main(int argc, char * argv[]) | |||
| 154 | 155 | ||
| 155 | opt = MY_OPT_SPACE; | 156 | opt = MY_OPT_SPACE; |
| 156 | base = 0; | 157 | base = 0; |
| 158 | order = "abxod"; | ||
| 157 | 159 | ||
| 158 | while((c = getopt_long(argc, argv, short_opt, long_opt, &opt_index)) != -1) | 160 | while((c = getopt_long(argc, argv, short_opt, long_opt, &opt_index)) != -1) |
| 159 | { | 161 | { |
| @@ -187,9 +189,14 @@ int main(int argc, char * argv[]) | |||
| 187 | base = 10; | 189 | base = 10; |
| 188 | break; | 190 | break; |
| 189 | 191 | ||
| 192 | case 'f': | ||
| 193 | order = optarg; | ||
| 194 | break; | ||
| 195 | |||
| 190 | case 'h': | 196 | case 'h': |
| 191 | my_usage(); | 197 | my_usage(); |
| 192 | return(0); | 198 | return(0); |
| 199 | |||
| 193 | case 'l': | 200 | case 'l': |
| 194 | opt |= MY_OPT_LIMIT; | 201 | opt |= MY_OPT_LIMIT; |
| 195 | break; | 202 | break; |
| @@ -282,7 +289,7 @@ int main(int argc, char * argv[]) | |||
| 282 | { | 289 | { |
| 283 | case -1: | 290 | case -1: |
| 284 | for(y = 0; (y < (int)strlen(argv[x])); y++) | 291 | for(y = 0; (y < (int)strlen(argv[x])); y++) |
| 285 | my_print(opt, (intmax_t)argv[x][y]); | 292 | my_print(opt, (intmax_t)argv[x][y], order); |
| 286 | break; | 293 | break; |
| 287 | 294 | ||
| 288 | default: | 295 | default: |
| @@ -297,7 +304,7 @@ int main(int argc, char * argv[]) | |||
| 297 | default: fprintf(stderr, "%s:%i: invalid hexadecimal number\n", PROGRAM_NAME, (int)(x - optind + 1)); return(1); | 304 | default: fprintf(stderr, "%s:%i: invalid hexadecimal number\n", PROGRAM_NAME, (int)(x - optind + 1)); return(1); |
| 298 | }; | 305 | }; |
| 299 | }; | 306 | }; |
| 300 | my_print(opt, num); | 307 | my_print(opt, num, order); |
| 301 | break; | 308 | break; |
| 302 | }; | 309 | }; |
| 303 | }; | 310 | }; |
| @@ -307,9 +314,10 @@ int main(int argc, char * argv[]) | |||
| 307 | 314 | ||
| 308 | 315 | ||
| 309 | // print value | 316 | // print value |
| 310 | void my_print(int32_t opt, uintmax_t num) | 317 | void my_print(int32_t opt, uintmax_t num, const char * order) |
| 311 | { | 318 | { |
| 312 | char buff[9]; | 319 | char buff[9]; |
| 320 | unsigned pos; | ||
| 313 | intmax_t y; | 321 | intmax_t y; |
| 314 | intmax_t z; | 322 | intmax_t z; |
| 315 | uintmax_t len; | 323 | uintmax_t len; |
| @@ -319,50 +327,84 @@ void my_print(int32_t opt, uintmax_t num) | |||
| 319 | max = sizeof(intmax_t); | 327 | max = sizeof(intmax_t); |
| 320 | len = 0; | 328 | len = 0; |
| 321 | 329 | ||
| 322 | if (opt & MY_OPT_LIMIT) | 330 | // determine padding |
| 323 | { | 331 | if (opt & MY_OPT_LIMIT) |
| 324 | max = 1; | 332 | { |
| 325 | for(y = 0; y < (intmax_t)sizeof(intmax_t); y++) | 333 | max = 1; |
| 326 | if ( (num >> (y*8)) & 0xFF ) | 334 | for(y = 0; y < (intmax_t)sizeof(intmax_t); y++) |
| 327 | max = (y+1); | 335 | if ( (num >> (y*8)) & 0xFF ) |
| 328 | }; | 336 | max = (y+1); |
| 329 | 337 | if (max < 2) | |
| 330 | // print ASCII value | 338 | max = 4; |
| 331 | if (opt & MY_OPT_ASCII) | 339 | }; |
| 332 | len = printf((len ? ((opt & MY_OPT_SPACE) ? ", '%c'" : ",'%c'") : "'%c'"), ((((num & 0xFF) >= 32) && ((num & 0xFF) <= 126)) ? (char)(num & 0xFF) : '.')); | ||
| 333 | 340 | ||
| 334 | // print binary value | 341 | for(pos = 0; (pos < strlen(order)); pos++) |
| 335 | if (opt & MY_OPT_BIN) | ||
| 336 | { | 342 | { |
| 337 | if (len) printf((opt & MY_OPT_SPACE) ? ", " : ","); | 343 | switch(order[pos]) |
| 338 | for(y = 0; ((uint32_t)y) < max; y++) | ||
| 339 | { | 344 | { |
| 340 | if (opt & MY_OPT_LEBYTE) | 345 | // print ASCII value |
| 341 | byte = num >> (8*y); | 346 | case 'A': |
| 342 | else | 347 | case 'a': |
| 343 | byte = num >> (8*(max-y-1)); | 348 | if ((opt & MY_OPT_ASCII) == 0) |
| 344 | if (opt & MY_OPT_LEBIT) | 349 | break; |
| 345 | for(z = 0; z < 8; z++) | 350 | len = printf((len ? ((opt & MY_OPT_SPACE) ? ", '%c'" : ",'%c'") : "'%c'"), ((((num & 0xFF) >= 32) && ((num & 0xFF) <= 126)) ? (char)(num & 0xFF) : '.')); |
| 346 | buff[z] = (byte & (0x01 << z)) ? '1' : '0'; | 351 | break; |
| 347 | if (!(opt & MY_OPT_LEBIT)) | ||
| 348 | for(z = 0; z < 8; z++) | ||
| 349 | buff[z] = (byte & (0x01 << (7-z))) ? '1' : '0'; | ||
| 350 | buff[z] = '\0'; | ||
| 351 | printf("%s", buff); | ||
| 352 | if ((opt & MY_OPT_SPACE) && (((uint32_t)y+1) < max)) | ||
| 353 | printf(" "); | ||
| 354 | }; | ||
| 355 | len = 1; | ||
| 356 | }; | ||
| 357 | 352 | ||
| 358 | // print hexadecimal value | 353 | // print binary value |
| 359 | if (opt & MY_OPT_HEX) len = printf((len ? ((opt & MY_OPT_SPACE) ? ", 0x%0*jX" : ",0x%0*jX") : "0x%0*jX"), (unsigned)(max*2), num); | 354 | case 'B': |
| 355 | case 'b': | ||
| 356 | if ((opt & MY_OPT_BIN) == 0) | ||
| 357 | break; | ||
| 358 | if (len) | ||
| 359 | printf((opt & MY_OPT_SPACE) ? ", " : ","); | ||
| 360 | for(y = 0; ((uint32_t)y) < max; y++) | ||
| 361 | { | ||
| 362 | if (opt & MY_OPT_LEBYTE) | ||
| 363 | byte = num >> (8*y); | ||
| 364 | else | ||
| 365 | byte = num >> (8*(max-y-1)); | ||
| 366 | if (opt & MY_OPT_LEBIT) | ||
| 367 | for(z = 0; z < 8; z++) | ||
| 368 | buff[z] = (byte & (0x01 << z)) ? '1' : '0'; | ||
| 369 | if (!(opt & MY_OPT_LEBIT)) | ||
| 370 | for(z = 0; z < 8; z++) | ||
| 371 | buff[z] = (byte & (0x01 << (7-z))) ? '1' : '0'; | ||
| 372 | buff[z] = '\0'; | ||
| 373 | printf("%s", buff); | ||
| 374 | if ((opt & MY_OPT_SPACE) && (((uint32_t)y+1) < max)) | ||
| 375 | printf(" "); | ||
| 376 | }; | ||
| 377 | len = 1; | ||
| 378 | break; | ||
| 360 | 379 | ||
| 361 | // print octal value | 380 | // print hexadecimal value |
| 362 | if (opt & MY_OPT_OCT) len = printf((len ? ((opt & MY_OPT_SPACE) ? ", 0%jo" : ",0%jo") : "0%jo"), num); | 381 | case 'X': |
| 382 | case 'x': | ||
| 383 | if ((opt & MY_OPT_HEX) == 0) | ||
| 384 | break; | ||
| 385 | len = printf((len ? ((opt & MY_OPT_SPACE) ? ", 0x%0*jX" : ",0x%0*jX") : "0x%0*jX"), (unsigned)(max*2), num); | ||
| 386 | break; | ||
| 387 | |||
| 388 | // print octal value | ||
| 389 | case 'O': | ||
| 390 | case 'o': | ||
| 391 | if ((opt & MY_OPT_OCT) == 0) | ||
| 392 | break; | ||
| 393 | len = printf((len ? ((opt & MY_OPT_SPACE) ? ", 0%jo" : ",0%jo") : "0%jo"), num); | ||
| 394 | break; | ||
| 363 | 395 | ||
| 364 | // print decimal value | 396 | // print decimal value |
| 365 | if (opt & MY_OPT_DEC) len = printf((len ? ((opt & MY_OPT_SPACE) ? ", %ju" : ",%ju") : "%ju"), num); | 397 | case 'D': |
| 398 | case 'd': | ||
| 399 | if ((opt & MY_OPT_DEC) == 0) | ||
| 400 | break; | ||
| 401 | len = printf((len ? ((opt & MY_OPT_SPACE) ? ", %ju" : ",%ju") : "%ju"), num); | ||
| 402 | break; | ||
| 403 | |||
| 404 | default: | ||
| 405 | break; | ||
| 406 | }; | ||
| 407 | }; | ||
| 366 | 408 | ||
| 367 | printf("\n"); | 409 | printf("\n"); |
| 368 | 410 | ||
| @@ -380,6 +422,7 @@ void my_usage() | |||
| 380 | printf(" -b assume binary notation for input\n"); | 422 | printf(" -b assume binary notation for input\n"); |
| 381 | printf(" -D enable decimal output\n"); | 423 | printf(" -D enable decimal output\n"); |
| 382 | printf(" -d assume decimal notation for input\n"); | 424 | printf(" -d assume decimal notation for input\n"); |
| 425 | printf(" -f order order of output values (default: \"abxod\")\n"); | ||
| 383 | printf(" -h, --help print this help and exit\n"); | 426 | printf(" -h, --help print this help and exit\n"); |
| 384 | printf(" -l print minimum number of bytes in hex and binary\n"); | 427 | printf(" -l print minimum number of bytes in hex and binary\n"); |
| 385 | printf(" -O enable octal output\n"); | 428 | printf(" -O enable octal output\n"); |
