New upstream version 2.1+git20190806.6c8d325
SZ Lin (林上智)
4 years ago
0 | 0 | --- |
1 | Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-*,modernize-*,bugprone-*,misc-*,-misc-unused-parameters,google-runtime-int,-llvm-header-guard,fuchsia-restrict-system-includes,-clang-analyzer-valist.Uninitialized,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-alpha.*,-readability-magic-numbers,-readability-braces-around-statements' | |
1 | Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-*,modernize-*,bugprone-*,misc-*,-misc-unused-parameters,google-runtime-int,-llvm-header-guard,fuchsia-restrict-system-includes,-clang-analyzer-valist.Uninitialized,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-alpha.*,-readability-magic-numbers,-readability-braces-around-statements,-readability-isolate-declaration' | |
2 | 2 | WarningsAsErrors: '*' |
3 | 3 | HeaderFilterRegex: '.*(?<!lookup3.c)$' |
4 | 4 | FormatStyle: 'file' |
0 | custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q |
3 | 3 | DOCDIR = $(DESTDIR)$(PREFIX)/share/doc/bcal |
4 | 4 | STRIP ?= strip |
5 | 5 | |
6 | CFLAGS ?= -O3 | |
7 | CFLAGS += -Wall -Wextra -Wno-unused-parameter -Werror | |
8 | LDLIBS = -lreadline | |
6 | CFLAGS_OPTIMIZATION ?= -O3 | |
7 | CFLAGS_WARNINGS ?= -Wall -Wextra -Wno-unused-parameter -Werror | |
8 | ||
9 | LDLIBS_READLINE ?= -lreadline | |
10 | ||
11 | CFLAGS += $(CFLAGS_OPTIMIZATION) $(CFLAGS_WARNINGS) | |
12 | LDLIBS += $(LDLIBS_READLINE) | |
9 | 13 | |
10 | 14 | SRC = $(wildcard src/*.c) |
11 | 15 | INCLUDE = -Iinc |
12 | 16 | |
13 | 17 | bcal: $(SRC) |
14 | $(CC) $(CFLAGS) $(INCLUDE) -o bcal $(SRC) $(LDLIBS) | |
18 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(INCLUDE) -o bcal $(SRC) $(LDLIBS) | |
15 | 19 | |
16 | 20 | all: bcal |
17 | 21 | |
18 | 22 | x86: $(SRC) |
19 | $(CC) -m64 $(CFLAGS) $(INCLUDE) -o bcal $(SRC) $(LDLIBS) | |
23 | $(CC) -m64 $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(INCLUDE) -o bcal $(SRC) $(LDLIBS) | |
20 | 24 | strip bcal |
21 | 25 | |
22 | 26 | distclean: clean |
6 | 6 | <a href="https://packages.debian.org/search?keywords=bcal&searchon=names&exact=1"><img src="https://img.shields.io/badge/debian-9+-blue.svg?maxAge=2592000" alt="Debian Stretch+" /></a> |
7 | 7 | <a href="https://apps.fedoraproject.org/packages/bcal"><img src="https://img.shields.io/badge/fedora-27+-blue.svg?maxAge=2592000" alt="Fedora 27+" /></a> |
8 | 8 | <a href="https://packages.ubuntu.com/search?keywords=bcal&searchon=names&exact=1"><img src="https://img.shields.io/badge/ubuntu-17.04+-blue.svg?maxAge=2592000" alt="Ubuntu Zesty+" /></a> |
9 | <a href="https://launchpad.net/~twodopeshaggy/+archive/ubuntu/jarun/"><img src="https://img.shields.io/badge/ubuntu-PPA-blue.svg?maxAge=2592000" alt="Ubuntu PPA" /></a> | |
10 | 9 | <p> |
11 | 10 | |
12 | 11 | <p align="center"> |
12 | <a href="https://repology.org/metapackage/bcal"><img src="https://repology.org/badge/tiny-repos/bcal.svg" alt="Availability"></a> | |
13 | 13 | <a href="https://travis-ci.org/jarun/bcal"><img src="https://img.shields.io/travis/jarun/bcal/master.svg" alt="Build Status" /></a> |
14 | 14 | <a href="https://scan.coverity.com/projects/jarun-bcal"><img src="https://img.shields.io/coverity/scan/17148.svg" alt="Coverity Scan Build Status" /></a> |
15 | 15 | <a href="https://github.com/jarun/bcal/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-GPLv3-yellow.svg?maxAge=2592000" alt="License" /></a> |
19 | 19 | <a href="https://asciinema.org/a/168719"><img src="https://asciinema.org/a/168719.png" alt="bcal_asciicast" width="600"/></a> |
20 | 20 | </p> |
21 | 21 | |
22 | `bcal` (*Byte CALculator*) is a REPL CLI utility for storage expressions, unit conversions or address calculations. If you can't calculate the hex address offset for (512 - 16) MiB, or the value when the 43<sup>rd</sup> bit of a 64-bit address is set mentally, `bcal` is for you. | |
22 | `bcal` (*Byte CALculator*) is a REPL CLI utility for storage expression evaluation, unit conversion and address calculation. If you can't calculate the hex address offset for (512 - 16) MiB, or the value when the 43<sup>rd</sup> bit of a 64-bit address is set mentally, `bcal` is for you. | |
23 | 23 | |
24 | 24 | It has a [`bc`](https://www.gnu.org/software/bc/manual/html_mono/bc.html) mode for general-purpose numerical calculations. |
25 | 25 | |
28 | 28 | *Love smart and efficient utilities? Explore [my repositories](https://github.com/jarun?tab=repositories). Buy me a cup of coffee if they help you.* |
29 | 29 | |
30 | 30 | <p align="center"> |
31 | <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q"><img src="https://img.shields.io/badge/PayPal-donate-green.svg" alt="Donate via PayPal!" /></a> | |
31 | <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q"><img src="https://img.shields.io/badge/PayPal-donate-1eb0fc.svg" alt="Donate via PayPal!" /></a> | |
32 | 32 | </p> |
33 | 33 | |
34 | 34 | ### Table of Contents |
71 | 71 | - [AUR](https://aur.archlinux.org/packages/bcal/) (`yay -S bcal`) |
72 | 72 | - [Debian](https://packages.debian.org/search?keywords=bcal&searchon=names&exact=1) (`apt-get install bcal`) |
73 | 73 | - [Fedora](https://apps.fedoraproject.org/packages/bcal) (`dnf install bcal`) |
74 | - [Homebrew](http://formulae.brew.sh/formula/bcal) (`brew install bcal`) | |
74 | - [FreeBSD](https://www.freshports.org/math/bcal/) (`pkg install bcal`) | |
75 | - [macOS/Homebrew](http://formulae.brew.sh/formula/bcal) (`brew install bcal`) | |
75 | 76 | - [NixOS](https://github.com/NixOS/nixpkgs/tree/master/pkgs/applications/science/math/bcal) (`nix-env -i bcal`) |
77 | - [pkgsrc](http://pkgsrc.se/math/bcal) (`pkg_add bcal`) | |
76 | 78 | - [Raspbian Testing](https://archive.raspbian.org/raspbian/pool/main/b/bcal/) (`apt-get install bcal`) |
77 | 79 | - [Ubuntu](https://packages.ubuntu.com/search?keywords=bcal&searchon=names&exact=1) (`apt-get install bcal`) |
78 | - [Ubuntu PPA](https://launchpad.net/~twodopeshaggy/+archive/ubuntu/jarun/) (`apt-get install bcal`) | |
79 | 80 | - [Void Linux](https://github.com/void-linux/void-packages/tree/master/srcpkgs/bcal) (`xbps-install -S bcal`) |
80 | 81 | |
81 | 82 | #### Release packages |
164 | 165 | - sector size: 0x200 (512) |
165 | 166 | - max heads per cylinder: 0x10 (16) |
166 | 167 | - max sectors per track: 0x3f (63) |
167 | - **bc variables**: `scale` = 10, `ibase` = 10. `last` and `r` are synced when toggling `bc` mode. `bc` is not called in minimal output mode. | |
168 | - **bc variables**: `scale` = 10, `ibase` = 10. `last` is synced to `r` when toggling from `bc` to `bcal`. Syncing `r` to `last` works with GNU `bc`. `bc` is not called in minimal output mode. | |
168 | 169 | |
169 | 170 | ### Examples |
170 | 171 |
62 | 62 | - max sectors per track: 0x3f (63) |
63 | 63 | .PP |
64 | 64 | .IP 10. 4 |
65 | \fBbc variables\fR: \fIscale\fR = 10, \fIibase\fR = 10. \fIlast\fR and \fIr\fR are synced when toggling \fIbc\fR mode. \fIbc\fR is not called in minimal output mode. | |
65 | \fBbc variables\fR: \fIscale\fR = 10, \fIibase\fR = 10. \fIlast\fR is synced to \fIr\fR when toggling from \fIbc\fR to \fBbcal\fR. Syncing \fIr\fR to \fIlast\fR works with GNU \fIbc\fR. \fIbc\fR is not called in minimal output mode. | |
66 | 66 | .SH OPTIONS |
67 | 67 | .TP |
68 | 68 | .BI "-c=" N |
12 | 12 | - gcc |
13 | 13 | deps: |
14 | 14 | - readline |
15 | container: "base/archlinux" | |
15 | container: "archlinux/base" | |
16 | 16 | centos7.1: |
17 | 17 | builddeps: |
18 | 18 | - make |
170 | 170 | static int try_bc(char *expr) |
171 | 171 | { |
172 | 172 | pid_t pid; |
173 | int pipe_pc[2], pipe_cp[2], ret; | |
173 | int pipe_pc[2], pipe_cp[2]; | |
174 | 174 | size_t len, count = 0; |
175 | ssize_t ret; | |
175 | 176 | |
176 | 177 | if (!expr) { |
177 | 178 | if (curexpr) |
204 | 205 | dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent |
205 | 206 | dup2(pipe_cp[1], STDERR_FILENO); // Give stderr to parent |
206 | 207 | |
207 | ret = execlp("bc", "bc", "-q", (char*) NULL); | |
208 | ret = execlp("bc", "bc", (char*) NULL); | |
208 | 209 | log(ERROR, "execlp() failed!\n"); |
209 | 210 | exit(ret); |
210 | 211 | } |
215 | 216 | exit(-1); |
216 | 217 | } |
217 | 218 | |
219 | #ifdef __GNU_LIBRARY__ | |
218 | 220 | if (write(pipe_pc[1], "last=", 5) != 5) { |
219 | 221 | log(ERROR, "write(2)! [%s]\n", strerror(errno)); |
220 | 222 | exit(-1); |
221 | 223 | } |
222 | 224 | |
223 | 225 | if (lastres.p[0]) { |
224 | ret = strlen(lastres.p); | |
226 | ret = (ssize_t)strlen(lastres.p); | |
225 | 227 | if (write(pipe_pc[1], lastres.p, ret) != ret) { |
226 | 228 | log(ERROR, "write(3)! [%s]\n", strerror(errno)); |
227 | 229 | exit(-1); |
237 | 239 | log(ERROR, "write(5)! [%s]\n", strerror(errno)); |
238 | 240 | exit(-1); |
239 | 241 | } |
240 | ||
241 | ret = strlen(expr); | |
242 | #endif | |
243 | ||
244 | ret = (ssize_t)strlen(expr); | |
242 | 245 | if (write(pipe_pc[1], expr, ret) != ret) { |
243 | 246 | log(ERROR, "write(6)! [%s]\n", strerror(errno)); |
244 | 247 | exit(-1); |
1161 | 1164 | |
1162 | 1165 | static int bstricmp(const char *s1, const char *s2) |
1163 | 1166 | { |
1164 | while (*s1 && (tolower(*s1) == tolower(*s2))) { | |
1167 | while ((int)*s1 && (tolower((int)*s1) == tolower((int)*s2))) { | |
1165 | 1168 | ++s1; |
1166 | 1169 | ++s2; |
1167 | 1170 | } |
1429 | 1432 | dequeue(front, rear, &arg); |
1430 | 1433 | |
1431 | 1434 | /* Check if arg is an operator */ |
1432 | if (strlen(arg.p) == 1 && !isdigit(arg.p[0])) { | |
1435 | if (strlen(arg.p) == 1 && !isdigit((int)arg.p[0])) { | |
1433 | 1436 | pop(&est, &raw_b); |
1434 | 1437 | pop(&est, &raw_a); |
1435 | 1438 | |
1608 | 1611 | } |
1609 | 1612 | |
1610 | 1613 | /* Check if a char is operator or not */ |
1611 | static int isoperator(char c) | |
1614 | static int isoperator(int c) | |
1612 | 1615 | { |
1613 | 1616 | switch (c) { |
1614 | 1617 | case '+': |
1648 | 1651 | if (!s || !*s) |
1649 | 1652 | return; |
1650 | 1653 | |
1651 | int len = strlen(s) - 1; | |
1654 | int len = (int)strlen(s) - 1; | |
1652 | 1655 | |
1653 | 1656 | if (s[len] == '\n') |
1654 | 1657 | --len; |
1655 | while (len >= 0 && (isspace(s[len]) || s[len] == '\"' || s[len] == '\'')) | |
1658 | while (len >= 0 && (isspace((int)s[len]) || s[len] == '\"' || s[len] == '\'')) | |
1656 | 1659 | --len; |
1657 | 1660 | s[len + 1] = '\0'; |
1658 | 1661 | |
1659 | 1662 | len = 0; |
1660 | while (s[len] && (isspace(s[len]) || s[len] == '\"' || s[len] == '\'')) | |
1663 | while (s[len] && (isspace((int)s[len]) || s[len] == '\"' || s[len] == '\'')) | |
1661 | 1664 | ++len; |
1662 | 1665 | |
1663 | 1666 | if (len) { |
1677 | 1680 | |
1678 | 1681 | while (*s != '\0') { |
1679 | 1682 | /* We should not combine 0xn b*/ |
1680 | if (!isspace(*s) || (*(s + 1) == 'b')) { | |
1683 | if (!isspace((int)*s) || (*(s + 1) == 'b')) { | |
1681 | 1684 | *p = *s; |
1682 | 1685 | ++p; |
1683 | 1686 | } |
1725 | 1728 | return NULL; |
1726 | 1729 | } |
1727 | 1730 | |
1728 | if (isoperator(exp[i]) && isalpha(exp[i + 1]) && (exp[i + 1] != 'r')) { | |
1731 | if (isoperator((int)exp[i]) && isalpha((int)exp[i + 1]) && (exp[i + 1] != 'r')) { | |
1729 | 1732 | log(ERROR, "invalid expression\n"); |
1730 | 1733 | free(parsed); |
1731 | 1734 | return NULL; |
1732 | 1735 | } |
1733 | 1736 | |
1734 | if ((isdigit(exp[i]) && isoperator(exp[i + 1])) || | |
1735 | (isoperator(exp[i]) && (isdigit(exp[i + 1]) || | |
1736 | isoperator(exp[i + 1]))) || | |
1737 | (isalpha(exp[i]) && isoperator(exp[i + 1])) || | |
1738 | (isoperator(exp[i]) && (exp[i + 1] == 'r'))) { | |
1737 | if ((isdigit((int)exp[i]) && isoperator((int)exp[i + 1])) || | |
1738 | (isoperator((int)exp[i]) && (isdigit((int)exp[i + 1]) || | |
1739 | isoperator((int)exp[i + 1]))) || | |
1740 | (isalpha((int)exp[i]) && isoperator((int)exp[i + 1])) || | |
1741 | (isoperator((int)exp[i]) && ((int)exp[i + 1] == 'r'))) { | |
1739 | 1742 | if (exp[i] == '<' || exp[i] == '>') { /* handle shift operators << and >> */ |
1740 | 1743 | if (prev != exp[i] && exp[i] != exp[i + 1]) { |
1741 | 1744 | log(ERROR, "invalid operator %c\n", exp[i]); |
1804 | 1807 | } |
1805 | 1808 | |
1806 | 1809 | if (!unit) { |
1807 | int unitchars = 0, len = strlen(value); | |
1810 | int unitchars = 0, len = (int)strlen(value); | |
1808 | 1811 | |
1809 | 1812 | while (len) { |
1810 | if (!isalpha(value[len - 1])) | |
1813 | if (!isalpha((int)value[len - 1])) | |
1811 | 1814 | break; |
1812 | 1815 | |
1813 | 1816 | ++unitchars; |
1922 | 1925 | char *expr = fixexpr(exp, &ret); /* Make parsing compatible */ |
1923 | 1926 | char *ptr; |
1924 | 1927 | |
1925 | log(DEBUG, "expr: %s\n", expr); | |
1928 | if (expr) | |
1929 | log(DEBUG, "expr: %s\n", expr); | |
1926 | 1930 | |
1927 | 1931 | if (expr == NULL) { |
1928 | 1932 | if (ret) |
2028 | 2032 | case 'f': |
2029 | 2033 | operation = 1; |
2030 | 2034 | |
2031 | if (tolower(*optarg) == 'c') { | |
2035 | if (tolower((int)*optarg) == 'c') { | |
2032 | 2036 | maxuint_t lba = 0; |
2033 | 2037 | |
2034 | 2038 | if (chs2lba(optarg + 1, &lba)) { |
2037 | 2041 | printhex_u128(lba); |
2038 | 2042 | printf("\n\n"); |
2039 | 2043 | } |
2040 | } else if (tolower(*optarg) == 'l') { | |
2044 | } else if (tolower((int)*optarg) == 'l') { | |
2041 | 2045 | t_chs chs; |
2042 | 2046 | |
2043 | 2047 | if (lba2chs(optarg + 1, &chs)) { |
2136 | 2140 | case 'b': |
2137 | 2141 | cfg.bcmode ^= 1; |
2138 | 2142 | if (cfg.bcmode) { |
2143 | #ifdef __GNU_LIBRARY__ | |
2139 | 2144 | printf("bc vars: scale = 10, ibase = 10, last = r\n"); |
2145 | #else | |
2146 | printf("bc vars: scale = 10, ibase = 10, last = 0\n"); | |
2147 | #endif | |
2140 | 2148 | strncpy(prompt, "bc> ", 5); |
2141 | 2149 | } else |
2142 | 2150 | strncpy(prompt, "bcal> ", 7); |