diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bfa5e4..27e1a3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install wcwidth + # python -m pip install wcwidth if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Script run: | diff --git a/graphs.cpp b/graphs.cpp index 3ddcdb7..7297cc0 100644 --- a/graphs.cpp +++ b/graphs.cpp @@ -219,7 +219,7 @@ int main() } } { - function afunction = [](auto x) + const function afunction = [](auto x) { return x + 1; }; graphs::options aoptions; diff --git a/graphs.hpp b/graphs.hpp index 47a40d3..dc642eb 100644 --- a/graphs.hpp +++ b/graphs.hpp @@ -169,7 +169,7 @@ namespace graphs template constexpr size_t size(const T &array) { - return distance(begin(array), end(array)); + return distance(cbegin(array), cend(array)); } // Number of columns needed to represent the string @@ -203,7 +203,7 @@ namespace graphs exit(1); } - int width = wcswidth(wcstring, length); + const int width = wcswidth(wcstring, length); if (width == -1) { cerr << "\nError! wcswidth failed. Nonprintable wide character.\n"; @@ -243,11 +243,9 @@ namespace graphs ++tempindex; } - char temp[templinelen + 1]; - strncpy(temp, words.data() + (index - linelen), templinelen); - temp[templinelen] = '\0'; + const string temp = words.substr(index - linelen, templinelen); - size_t width = strcol(temp); + const size_t width = strcol(temp.c_str()); if (width >= line_length) { @@ -327,7 +325,7 @@ namespace graphs if (number and anumber < 1000 and power > 0) { strm << setprecision(LDBL_DIG) << number; - string str = strm.str(); + const string str = strm.str(); const unsigned length = 5 + (number < 0 ? 1 : 0); if (str.length() > length) @@ -358,7 +356,7 @@ namespace graphs if (n <= MAX) { long double intpart = 0; - long double fractionpart = abs(modf(number, &intpart)); + const long double fractionpart = abs(modf(number, &intpart)); for (size_t i = 0; i < graphs::size(fractions) and !output; ++i) { @@ -442,7 +440,7 @@ namespace graphs break; } - size_t length = strcol(strm.str().c_str()); + const size_t length = strcol(strm.str().c_str()); return length; } @@ -542,7 +540,7 @@ namespace graphs { bool output = false; long double label = 0; - int adivisor = i < yaxis ? -ydivisor : ydivisor; + const int adivisor = i < yaxis ? -ydivisor : ydivisor; for (long double k = yaxis + adivisor; (i < yaxis ? k >= i : k < (i + ai)) and i >= ai and !output; k += adivisor) { @@ -592,7 +590,7 @@ namespace graphs } else if (axistick) { - int adivisor = i < yaxis ? -ydivisor : ydivisor; + const int adivisor = i < yaxis ? -ydivisor : ydivisor; for (long double k = yaxis + adivisor; (i < yaxis ? k >= i : k < (i + ai)) and i >= ai and !output; k += adivisor) { @@ -623,7 +621,7 @@ namespace graphs } else if (axistick) { - int adivisor = j < xaxis ? -xdivisor : xdivisor; + const int adivisor = j < xaxis ? -xdivisor : xdivisor; for (long double k = xaxis + adivisor; (j < xaxis ? k >= j : k < (j + aj)) and j < (width - (aj * 2)) and !output; k += adivisor) { @@ -653,7 +651,7 @@ namespace graphs else if (yaxislabel and axistick and axisunitslabel) { long double label = 0; - int adivisor = j < xaxis ? -xdivisor : xdivisor; + const int adivisor = j < xaxis ? -xdivisor : xdivisor; if (j < xaxis) j += aj; @@ -768,7 +766,7 @@ namespace graphs cout << astyle[10]; } - cout << endl; + cout << '\n'; return 0; } @@ -891,8 +889,8 @@ namespace graphs if (!graphs::size(arrays)) return 1; - if (!all_of(begin(arrays), end(arrays), [](const auto &array) - { return all_of(begin(array), end(array), [](const auto &x) + if (!all_of(cbegin(arrays), cend(arrays), [](const auto &array) + { return all_of(cbegin(array), cend(array), [](const auto &x) { return graphs::size(x) == 2; }); })) { cerr << "Error: The arrays must have two columns.\n"; @@ -1094,7 +1092,7 @@ namespace graphs for (size_t j = 0; j < numfunctions; ++j) { - unsigned short acolor = numfunctions == 1 ? color + 1 : (j % (graphs::size(colors) - 2)) + 3; + const unsigned short acolor = numfunctions == 1 ? color + 1 : (j % (graphs::size(colors) - 2)) + 3; for (size_t i = 0; i < rows * xres; ++i) { diff --git a/python/README.md b/python/README.md index 9276a1f..bd87afd 100644 --- a/python/README.md +++ b/python/README.md @@ -25,7 +25,7 @@ ### Usage -Requires Python 3.6 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: +Requires Python 3.6 or greater and if not on Linux or macOS, the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: ```bash pip3 install wcwidth # or @@ -247,7 +247,7 @@ Check that the width of the table is not greater then the width of the terminal. ### Usage -Requires Python 3.6 or greater and the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: +Requires Python 3.6 or greater and if not on Linux or macOS, the [wcwidth library](https://pypi.org/project/wcwidth/), which users can install with: ```bash pip3 install wcwidth # or diff --git a/python/graphs.py b/python/graphs.py index ad4947c..2eddce3 100644 --- a/python/graphs.py +++ b/python/graphs.py @@ -12,7 +12,20 @@ from enum import Enum, IntEnum, auto from fractions import Fraction from typing import Callable, List, Optional, Sequence, Tuple -from wcwidth import wcswidth +if sys.platform != "win32": + import ctypes + from ctypes.util import find_library + + libc = ctypes.CDLL(find_library("c")) + libc.wcwidth.argtypes = (ctypes.c_wchar,) + libc.wcwidth.restype = ctypes.c_int + libc.wcswidth.argtypes = (ctypes.c_wchar_p, ctypes.c_int) + libc.wcswidth.restype = ctypes.c_int + + def wcswidth(astr: str) -> int: + return libc.wcswidth(astr, len(astr)) +else: + from wcwidth import wcswidth locale.setlocale(locale.LC_ALL, "") @@ -28,17 +41,17 @@ class style_types(IntEnum): heavy_dashed = auto() -styles = [ - ["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII - ["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic - ["─", "│", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"], # Light - ["━", "┃", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"], # Heavy - ["═", "║", "╔", "╦", "╗", "╠", "╬", "╣", "╚", "╩", "╝"], # Double - ["─", "│", "╭", "┬", "╮", "├", "┼", "┤", "╰", "┴", "╯"], # Light Arc - ["╌", "┊", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"], # Light Dashed - ["╍", "┋", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"] # Heavy Dashed - # [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]] #No border -] +styles = ( + ("-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"), # ASCII + ("—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"), # Basic + ("─", "│", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"), # Light + ("━", "┃", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"), # Heavy + ("═", "║", "╔", "╦", "╗", "╠", "╬", "╣", "╚", "╩", "╝"), # Double + ("─", "│", "╭", "┬", "╮", "├", "┼", "┤", "╰", "┴", "╯"), # Light Arc + ("╌", "┊", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"), # Light Dashed + ("╍", "┋", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛") # Heavy Dashed + # (" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")) #No border +) class color_types(IntEnum): @@ -61,12 +74,12 @@ class color_types(IntEnum): white = auto() -colors = ["\033[39m", "\033[30m", "\033[31m", "\033[32m", "\033[33m", +colors = ("\033[39m", "\033[30m", "\033[31m", "\033[32m", "\033[33m", "\033[34m", "\033[35m", "\033[36m", "\033[37m", "\033[90m", "\033[91m", "\033[92m", "\033[93m", "\033[94m", "\033[95m", - "\033[96m", "\033[97m"] + "\033[96m", "\033[97m") -dots = [ +dots = ( "⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⠨", "⠩", "⠪", "⠫", "⠬", @@ -84,14 +97,14 @@ dots = [ "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", - "⣿"] -dotvalues = [[0x1, 0x2, 0x4, 0x40], [0x8, 0x10, 0x20, 0x80]] + "⣿") +dotvalues = ((0x1, 0x2, 0x4, 0x40), (0x8, 0x10, 0x20, 0x80)) -blocks = [" ", "▖", "▗", "▄", "▘", "▌", "▚", - "▙", "▝", "▞", "▐", "▟", "▀", "▛", "▜", "█"] -blockvalues = [[4, 1], [8, 2]] +blocks = (" ", "▖", "▗", "▄", "▘", "▌", "▚", + "▙", "▝", "▞", "▐", "▟", "▀", "▛", "▜", "█") +blockvalues = ((4, 1), (8, 2)) -bars = [" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"] +bars = (" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█") class type_types(IntEnum): @@ -101,8 +114,8 @@ class type_types(IntEnum): atype_types = (type_types.braille, type_types.block) -marks = [[[0, 0]], [[0, 1], [-1, 0], [0, 0], [1, 0], [0, -1]], - [[-1, 1], [0, 1], [1, 1], [-1, 0], [1, 0], [-1, -1], [0, -1], [1, -1]]] +marks = (((0, 0),), ((0, 1), (-1, 0), (0, 0), (1, 0), (0, -1)), + ((-1, 1), (0, 1), (1, 1), (-1, 0), (1, 0), (-1, -1), (0, -1), (1, -1))) class mark_types(IntEnum): @@ -151,7 +164,7 @@ class units_types(Enum): monetary = auto() -suffix_power_char = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"] +suffix_power_char = ("", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q") MAX = sys.float_info.radix ** sys.float_info.mant_dig - 1 @@ -209,6 +222,7 @@ def outputunit(number: float, scale: units_types) -> str: else: strm = locale.format_string("%.0f", number, grouping=True) + # "k" if power == 1 and scale == scale_SI else strm += suffix_power_char[power] if power < len( suffix_power_char) else "(error)" diff --git a/python/tables.py b/python/tables.py index 040566f..fa9617f 100644 --- a/python/tables.py +++ b/python/tables.py @@ -10,7 +10,20 @@ import textwrap from enum import IntEnum, auto from typing import Any, Callable, List, Optional, Sequence -from wcwidth import wcswidth +if sys.platform != "win32": + import ctypes + from ctypes.util import find_library + + libc = ctypes.CDLL(find_library("c")) + libc.wcwidth.argtypes = (ctypes.c_wchar,) + libc.wcwidth.restype = ctypes.c_int + libc.wcswidth.argtypes = (ctypes.c_wchar_p, ctypes.c_int) + libc.wcswidth.restype = ctypes.c_int + + def wcswidth(astr: str) -> int: + return libc.wcswidth(astr, len(astr)) +else: + from wcwidth import wcswidth locale.setlocale(locale.LC_ALL, "") @@ -26,17 +39,17 @@ class style_types(IntEnum): heavy_dashed = auto() -styles = [ - ["-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # ASCII - ["—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"], # Basic - ["─", "│", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"], # Light - ["━", "┃", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"], # Heavy - ["═", "║", "╔", "╦", "╗", "╠", "╬", "╣", "╚", "╩", "╝"], # Double - ["─", "│", "╭", "┬", "╮", "├", "┼", "┤", "╰", "┴", "╯"], # Light Arc - ["╌", "┊", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"], # Light Dashed - ["╍", "┋", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"] # Heavy Dashed - # [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]] #No border -] +styles = ( + ("-", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"), # ASCII + ("—", "|", "+", "+", "+", "+", "+", "+", "+", "+", "+"), # Basic + ("─", "│", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"), # Light + ("━", "┃", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛"), # Heavy + ("═", "║", "╔", "╦", "╗", "╠", "╬", "╣", "╚", "╩", "╝"), # Double + ("─", "│", "╭", "┬", "╮", "├", "┼", "┤", "╰", "┴", "╯"), # Light Arc + ("╌", "┊", "┌", "┬", "┐", "├", "┼", "┤", "└", "┴", "┘"), # Light Dashed + ("╍", "┋", "┏", "┳", "┓", "┣", "╋", "┫", "┗", "┻", "┛") # Heavy Dashed + # (" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")) #No border +) ansi = re.compile(r"\x1B\[(?:[0-9]+(?:;[0-9]+)*)?m") diff --git a/tables.cpp b/tables.cpp index 84625af..c768b6b 100644 --- a/tables.cpp +++ b/tables.cpp @@ -521,7 +521,7 @@ int main() } } { - function afunction = [](auto x) + const function afunction = [](auto x) { return x + 1; }; tables::options aoptions; diff --git a/tables.hpp b/tables.hpp index e051951..fb4255d 100644 --- a/tables.hpp +++ b/tables.hpp @@ -65,7 +65,7 @@ namespace tables template constexpr size_t size(const T &array) { - return distance(begin(array), end(array)); + return distance(cbegin(array), cend(array)); } // Number of columns needed to represent the string @@ -102,7 +102,7 @@ namespace tables exit(1); } - int width = wcswidth(wcstring, length); + const int width = wcswidth(wcstring, length); if (width == -1) { cerr << "\nError! wcswidth failed. Nonprintable wide character.\n"; @@ -142,11 +142,9 @@ namespace tables ++tempindex; } - char temp[templinelen + 1]; - strncpy(temp, words.data() + (index - linelen), templinelen); - temp[templinelen] = '\0'; + const string temp = words.substr(index - linelen, templinelen); - size_t width = strcol(temp); + const size_t width = strcol(temp.c_str()); if (width >= line_length) { @@ -183,9 +181,7 @@ namespace tables const size_t rows = array.size(); const size_t columns = array[0].size(); - int columnwidth[columns]; - for (size_t j = 0; j < columns; ++j) - columnwidth[j] = 0; + vector columnwidth(columns); setlocale(LC_ALL, ""); @@ -202,7 +198,7 @@ namespace tables struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); - size_t width = accumulate(columnwidth, columnwidth + columns, 0ul); + size_t width = accumulate(columnwidth.cbegin(), columnwidth.cend(), 0ul); if (tableborder or cellborder or headerrow or headercolumn) width += (((2 * padding) + 1) * columns) + (tableborder ? 1 : -1); @@ -344,7 +340,7 @@ namespace tables cout << astyle[10]; } - cout << endl; + cout << '\n'; return 0; } @@ -362,7 +358,7 @@ namespace tables size_t rows = tables::size(aarray); size_t columns = tables::size(aarray[0]); - if (!all_of(begin(aarray), end(aarray), [columns](const auto &x) + if (!all_of(cbegin(aarray), cend(aarray), [&columns](const auto &x) { return tables::size(x) == columns; })) { cerr << "Error: The rows of the array must have the same number of columns.\n"; @@ -520,7 +516,7 @@ namespace tables aarray[i][j + 1] = (functions[j])(aarray[i][0]); } - int code = array(aarray, headerrow, headercolumn, aoptions); + const int code = array(aarray, headerrow, headercolumn, aoptions); if (headerrow) {