1// Port of 'cat' - concatenate files and print on the standard output for GNU.
2// 'cat' file concatenation program for Phasor.
3// Copyright (C) 2026 Daniel McGuire.
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
18// Include standard libraries
24// Global variables for options
25var g_show_all = false; // -A, --show-all
26var g_number_nonblank = false; // -b, --number-nonblank
27var g_show_ends = false; // -e, -E, --show-ends
28var g_number = false; // -n, --number
29var g_squeeze_blank = false; // -s, --squeeze-blank
30var g_show_tabs = false; // -t, -T, --show-tabs
31var g_show_nonprinting = false; // -v, --show-nonprinting
36fn startsWith(input: string, prefix: string) {
37 if (len(input) < len(prefix)) return false;
38 return substr(input, 0, len(prefix)) == prefix;
41// Function to display help message
42fn show_help() -> void {
43 puts("Usage: cat [OPTION]... [FILE]...");
44 puts("Concatenate FILE(s) to standard output.");
46 puts("With no FILE, or when FILE is -, read standard input.");
49 puts(" -A, --show-all equivalent to -vET");
50 puts(" -b, --number-nonblank number nonempty output lines, overrides -n");
51 puts(" -e equivalent to -vE");
52 puts(" -E, --show-ends display $ at end of each line");
53 puts(" -n, --number number all output lines");
54 puts(" -s, --squeeze-blank suppress repeated empty output lines");
55 puts(" -t equivalent to -vT");
56 puts(" -T, --show-tabs display TAB characters as ^I");
57 puts(" -u (ignored)");
58 puts(" -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB");
59 puts(" --help display this help and exit");
60 puts(" --version output version information and exit");
63 puts(" cat f - g Output f's contents, then standard input, then g's contents.");
64 puts(" cat Copy standard input to standard output.");
66 puts("GNU coreutils online help: <https://www.gnu.org/software/coreutils/>");
67 puts("Report any translation bugs to <https://translationproject.org/team/>");
70// Function to display version information
71fn show_version() -> void {
72 puts("cat (Phasor coreutils) 0.1");
73 puts("License GPLv3+: GNU GPL version 3 or later");
74 puts("This is free software: you are free to change and redistribute it.");
75 puts("There is NO WARRANTY, to the extent permitted by law.");
77 puts("Written by Daniel McGuire");
80// Process a file (or stdin if filename is "-")
81fn process_file(filename: string) -> void {
82 if (filename == "-") {
84 while (line != null) {
91 if (!fexists(filename)) {
92 puts_error("cat: file not found");
96 var content = fread(filename);
97 if (content != null) {
104 var arg_count = sys_argc();
107 if (arg_count == 1) {
113 for (; i < arg_count; i = i + 1) {
114 var arg = sys_argv(i);
121 if (!startsWith(arg, "-")) break;
123 if (arg == "--help") {
128 if (arg == "--version") {
133 if (arg == "-A" || arg == "--show-all") {
135 g_show_nonprinting = true;
141 if (arg == "-b" || arg == "--number-nonblank") {
142 g_number_nonblank = true;
148 g_show_nonprinting = true;
153 if (arg == "-E" || arg == "--show-ends") {
158 if (arg == "-n" || arg == "--number") {
159 if (!g_number_nonblank) g_number = true;
163 if (arg == "-s" || arg == "--squeeze-blank") {
164 g_squeeze_blank = true;
169 g_show_nonprinting = true;
174 if (arg == "-T" || arg == "--show-tabs") {
179 if (arg == "-v" || arg == "--show-nonprinting") {
180 g_show_nonprinting = true;
184 puts_error("cat: invalid option");
185 puts("Try 'cat --help' for more information.");
190 if (i >= arg_count) {
193 while (i < arg_count) {
194 process_file(sys_argv(i));