/* unit-cvt.c - test cvt.c * * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2 **************************************************************** * Copyright (C) 2000 Thomas Lord * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/os/errno.h" #include "hackerlab/fmt/cvt.h" #include "hackerlab/cmd/main.h" static t_uchar * program_name = "unit-cvt"; static t_uchar * usage = "[options]"; static t_uchar * version_string = "1.0"; #define OPTS(OP, OP2) \ OP (opt_help_msg, "h", "help", 0, \ "Display a help message and exit.") \ OP (opt_version, "V", "version", 0, \ "Display a release identifier string") \ OP2 (opt_version, 0, 0, 0, "and exit.") \ OP (opt_sizeof_long, 0, "sl", 0, \ "Print the number of bytes in a long integer.") \ OP (opt_sizeof_int, 0, "si", 0, \ "Print the number of bytes in an integer.") \ OP (opt_ulong_decimal, 0, "uld N", 1, \ "Decimal number to unsigned long.") \ OP (opt_long_decimal, 0, "ld N", 1, \ "Decimal number to long.") \ OP (opt_uint_decimal, 0, "ud N", 1, \ "Decimal number to unsigned integer.") \ OP (opt_int_decimal, 0, "d N", 1, \ "Decimal number to integer.") \ OP (opt_ulong_hex, 0, "ulx N", 1, \ "Hexadecimal number to unsigned long.") \ OP (opt_long_hex, 0, "lx N", 1, \ "Hexadecimal number to long.") \ OP (opt_uint_hex, 0, "ux N", 1, \ "Hexadecimal number to unsigned integer.") \ OP (opt_int_hex, 0, "x N", 1, \ "Hexadecimal number to integer.") \ OP (opt_ulong_HEX, 0, "ulX N", 1, \ "Hexadecimal number to unsigned long.") \ OP (opt_long_HEX, 0, "lX N", 1, \ "Hexadecimal number to long.") \ OP (opt_uint_HEX, 0, "uX N", 1, \ "Hexadecimal number to unsigned integer.") \ OP (opt_int_HEX, 0, "X N", 1, \ "Hexadecimal number to integer.") \ OP (opt_ulong_octal, 0, "ulo N", 1, \ "Octal number to unsigned long.") \ OP (opt_long_octal, 0, "lo N", 1, \ "Octal number to long.") \ OP (opt_uint_octal, 0, "uo N", 1, \ "Octal number to unsigned integer.") \ OP (opt_int_octal, 0, "o N", 1, \ "Octal number to integer.") enum options { OPTS (OPT_ENUM, OPT_IGN) }; struct opt_desc opts[] = { OPTS (OPT_DESC, OPT_DESC) {-1, 0, 0, 0, 0} }; int main (int argc, char * argv[]) { int o; struct opt_parsed * option; option = 0; while (1) { int errn; unsigned long ul; unsigned int ui; long l; int i; int cvt_result; t_uchar buf[100]; o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, 0, opt_help_msg, opt_none, opt_version); if (o == opt_none) break; switch (o) { default: safe_printfmt (2, "unhandled option `%s'\n", option->opt_string); panic ("internal error parsing arguments"); #if 0 usage_error: opt_usage (2, argv[0], program_name, usage, 1); panic_exit (); bogus_arg: safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string); goto usage_error; #endif case opt_sizeof_long: printfmt (&errn, 1, "%lu\n", (t_ulong)sizeof (long)); break; case opt_sizeof_int: printfmt (&errn, 1, "%lu\n", (t_ulong)sizeof (int)); break; case opt_ulong_decimal: cvt_result = cvt_decimal_to_ulong (&errn, &ul, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_decimal (buf, ul); goto generic_cvt_test; case opt_long_decimal: cvt_result = cvt_decimal_to_long (&errn, &l, option->arg_string, str_length (option->arg_string)); cvt_long_to_decimal (buf, l); goto generic_cvt_test; case opt_uint_decimal: cvt_result = cvt_decimal_to_uint (&errn, &ui, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_decimal (buf, ui); goto generic_cvt_test; case opt_int_decimal: cvt_result = cvt_decimal_to_int (&errn, &i, option->arg_string, str_length (option->arg_string)); cvt_long_to_decimal (buf, i); goto generic_cvt_test; case opt_ulong_hex: cvt_result = cvt_hex_to_ulong (&errn, &ul, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_hex (buf, ul); goto generic_cvt_test; case opt_long_hex: cvt_result = cvt_hex_to_long (&errn, &l, option->arg_string, str_length (option->arg_string)); cvt_long_to_hex (buf, l); goto generic_cvt_test; case opt_uint_hex: cvt_result = cvt_hex_to_uint (&errn, &ui, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_hex (buf, ui); goto generic_cvt_test; case opt_int_hex: cvt_result = cvt_hex_to_int (&errn, &i, option->arg_string, str_length (option->arg_string)); cvt_long_to_hex (buf, i); goto generic_cvt_test; case opt_ulong_HEX: cvt_result = cvt_hex_to_ulong (&errn, &ul, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_HEX (buf, ul); goto generic_cvt_test; case opt_long_HEX: cvt_result = cvt_hex_to_long (&errn, &l, option->arg_string, str_length (option->arg_string)); cvt_long_to_HEX (buf, l); goto generic_cvt_test; case opt_uint_HEX: cvt_result = cvt_hex_to_uint (&errn, &ui, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_HEX (buf, ui); goto generic_cvt_test; case opt_int_HEX: cvt_result = cvt_hex_to_int (&errn, &i, option->arg_string, str_length (option->arg_string)); cvt_long_to_HEX (buf, i); goto generic_cvt_test; case opt_ulong_octal: cvt_result = cvt_octal_to_ulong (&errn, &ul, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_octal (buf, ul); goto generic_cvt_test; case opt_long_octal: cvt_result = cvt_octal_to_long (&errn, &l, option->arg_string, str_length (option->arg_string)); cvt_long_to_octal (buf, l); goto generic_cvt_test; case opt_uint_octal: cvt_result = cvt_octal_to_uint (&errn, &ui, option->arg_string, str_length (option->arg_string)); cvt_ulong_to_octal (buf, ui); goto generic_cvt_test; case opt_int_octal: cvt_result = cvt_octal_to_int (&errn, &i, option->arg_string, str_length (option->arg_string)); cvt_long_to_octal (buf, i); goto generic_cvt_test; generic_cvt_test: if (cvt_result) printfmt (&errn, 1, "%s\n", ((errn == EINVAL) ? "EINVAL" : ((errn == ERANGE) ? "ERANGE" : "unexpected errno value"))); else { printfmt (&errn, 1, "%s\n", buf); } return errn; break; } { t_uchar nbuf[32]; size_t needed; invariant ((cvt_long_to_decimal (nbuf, -1) == 2) && !str_cmp (nbuf, "-1")); invariant ((cvt_long_to_HEX (nbuf, -1) == 2) && !str_cmp (nbuf, "-1")); invariant ((cvt_long_to_hex (nbuf, -1) == 2) && !str_cmp (nbuf, "-1")); invariant ((cvt_long_to_octal (nbuf, -1) == 2) && !str_cmp (nbuf, "-1")); invariant (cvt_ulong_to_decimal_n (nbuf, 32, 123, &needed) == 0 && str_cmp (nbuf,"123") == 0 && needed == 3); invariant (cvt_ulong_to_decimal_n (nbuf, 2, 123, &needed) == -1 && needed == 3); invariant (cvt_long_to_decimal_n (nbuf, 32, -123, &needed) == 0 && str_cmp (nbuf,"-123") == 0 && needed == 4); invariant (cvt_long_to_decimal_n (nbuf, 2, -123, &needed) == -1 && needed == 4); invariant (cvt_ulong_to_octal_n (nbuf, 32, 123, &needed) == 0 && str_cmp (nbuf,"173") == 0 && needed == 3); invariant (cvt_ulong_to_octal_n (nbuf, 2, 123, &needed) == -1 && needed == 3); invariant (cvt_long_to_octal_n (nbuf, 32, -123, &needed) == 0 && str_cmp (nbuf,"-173") == 0 && needed == 4); invariant (cvt_long_to_octal_n (nbuf, 2, -123, &needed) == -1 && needed == 4); invariant (cvt_ulong_to_HEX_n (nbuf, 32, 123, &needed) == 0 && str_cmp (nbuf,"7B") == 0 && needed == 2); invariant (cvt_ulong_to_HEX_n (nbuf, 1, 123, &needed) == -1 && needed == 2); invariant (cvt_long_to_HEX_n (nbuf, 32, -123, &needed) == 0 && str_cmp (nbuf,"-7B") == 0 && needed == 3); invariant (cvt_long_to_HEX_n (nbuf, 1, -123, &needed) == -1 && needed == 3); invariant (cvt_ulong_to_hex_n (nbuf, 32, 123, &needed) == 0 && str_cmp (nbuf,"7b") == 0 && needed == 2); invariant (cvt_ulong_to_hex_n (nbuf, 1, 123, &needed) == -1 && needed == 2); invariant (cvt_long_to_hex_n (nbuf, 32, -123, &needed) == 0 && str_cmp (nbuf,"-7b") == 0 && needed == 3); invariant (cvt_long_to_hex_n (nbuf, 1, -123, &needed) == -1 && needed == 3); } { const t_uchar * good="1234567noobar"; const t_uchar * ngood="-1234567noobar"; const t_uchar * bad="+noobar1234567"; const t_uchar * toobig="1234567123456712345671234567noobar"; int err; unsigned long ul; unsigned int ui; long sl; int si; size_t consumed; invariant (cvt_scan_decimal_to_ulong (&err, &ul, &consumed, good, 13) == 0 && ul == 1234567 && consumed == 7); invariant (cvt_scan_decimal_to_ulong (&err, &ul, &consumed, bad, 14) == -1 && err == EINVAL); invariant (cvt_scan_decimal_to_ulong (&err, &ul, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_decimal_to_uint (&err, &ui, &consumed, good, 13) == 0 && ui == 1234567 && consumed == 7); invariant (cvt_scan_decimal_to_uint (&err, &ui, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_decimal_to_uint (&err, &ui, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_decimal_to_long (&err, &sl, &consumed, ngood, 14) == 0 && sl == -1234567 && consumed == 8); invariant (cvt_scan_decimal_to_long (&err, &sl, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_decimal_to_long (&err, &sl, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_decimal_to_int (&err, &si, &consumed, ngood, 14) == 0 && si == -1234567 && consumed == 8); invariant (cvt_scan_decimal_to_int (&err, &si, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_decimal_to_int (&err, &si, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_hex_to_ulong (&err, &ul, &consumed, good, 13) == 0 && ul == 0x1234567 && consumed == 7); invariant (cvt_scan_hex_to_ulong (&err, &ul, &consumed, bad, 14) == -1 && err == EINVAL); invariant (cvt_scan_hex_to_ulong (&err, &ul, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_hex_to_uint (&err, &ui, &consumed, good, 13) == 0 && ui == 0x1234567 && consumed == 7); invariant (cvt_scan_hex_to_uint (&err, &ui, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_hex_to_uint (&err, &ui, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_hex_to_long (&err, &sl, &consumed, ngood, 14) == 0 && sl == -0x1234567 && consumed == 8); invariant (cvt_scan_hex_to_long (&err, &sl, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_hex_to_long (&err, &sl, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_hex_to_int (&err, &si, &consumed, ngood, 14) == 0 && si == -0x1234567 && consumed == 8); invariant (cvt_scan_hex_to_int (&err, &si, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_hex_to_int (&err, &si, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_octal_to_ulong (&err, &ul, &consumed, good, 13) == 0 && ul == 01234567 && consumed == 7); invariant (cvt_scan_octal_to_ulong (&err, &ul, &consumed, bad, 14) == -1 && err == EINVAL); invariant (cvt_scan_octal_to_ulong (&err, &ul, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_octal_to_uint (&err, &ui, &consumed, good, 13) == 0 && ui == 01234567 && consumed == 7); invariant (cvt_scan_octal_to_uint (&err, &ui, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_octal_to_uint (&err, &ui, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_octal_to_long (&err, &sl, &consumed, ngood, 14) == 0 && sl == -01234567 && consumed == 8); invariant (cvt_scan_octal_to_long (&err, &sl, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_octal_to_long (&err, &sl, &consumed, toobig, 34) == -1 && err == ERANGE); invariant (cvt_scan_octal_to_int (&err, &si, &consumed, ngood, 14) == 0 && si == -01234567 && consumed == 8); invariant (cvt_scan_octal_to_int (&err, &si, &consumed, bad, 13) == -1 && err == EINVAL); invariant (cvt_scan_octal_to_int (&err, &si, &consumed, toobig, 34) == -1 && err == ERANGE); } } return 0; }