From b11be1cabd7e2efd7f548267e93f40451e296c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Sat, 29 Jul 2023 04:56:33 +0900 Subject: [PATCH] =?UTF-8?q?true=E3=80=81false=E3=80=81=E3=81=A8wc=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 + Makefile | 18 ++++- false.zig | 3 + true.zig | 3 + wc.zig | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 false.zig create mode 100644 true.zig create mode 100644 wc.zig diff --git a/CHANGELOG.md b/CHANGELOG.md index 16e2822..1939281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,3 +9,6 @@ * rmを追加(完了) * touchを追加 * whoamiを追加(完了) +* trueを追加(完了) +* falseを追加(完了) +* wcを追加(完了) diff --git a/Makefile b/Makefile index 77c9b3e..7714d0a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ NAME=coreutils VERSION := $(shell cat version.zig | grep "pub const version" | awk '{print $$5}' | sed "s/\"//g" | sed "s/;//") PREFIX=/usr MANPREFIX=${PREFIX}/share/man -PROG=cat cp ls mkdir pwd rm touch +PROG=cat cp echo false groups ls mkdir pwd rm touch true wc whoami CC=zig build-exe RELEASE=ReleaseSmall @@ -14,7 +14,21 @@ all: ${PROG} mv $@ bin mv $@.o bin +loc-install: all + mkdir -p ~/.local/bin + for prog in ${PROG}; do \ + cp bin/$$prog ~/.local/bin; \ + chmod +x ~/.local/bin/$$prog; \ + done + +sys-install: all + mkdir -p ${PREFIX}/bin + for prog in ${PROG}; do \ + cp bin/$$prog ${PREFIX}/bin; \ + chmod +x ${PREFIX}/bin/$$prog; \ + done + clean: rm -rf bin/${PROG} -.PHONY: all clean +.PHONY: all loc-install sys-install clean diff --git a/false.zig b/false.zig new file mode 100644 index 0000000..26f903e --- /dev/null +++ b/false.zig @@ -0,0 +1,3 @@ +pub fn main() !u8 { + return 1; +} diff --git a/true.zig b/true.zig new file mode 100644 index 0000000..4523fef --- /dev/null +++ b/true.zig @@ -0,0 +1,3 @@ +pub fn main() !u8 { + return 0; +} diff --git a/wc.zig b/wc.zig new file mode 100644 index 0000000..e7547cc --- /dev/null +++ b/wc.zig @@ -0,0 +1,217 @@ +const std = @import("std"); +const fs = std.fs; +const io = std.io; + +const version = @import("version.zig").version; + +fn help() !void { + const stdof = io.getStdOut().writer(); + var bw = io.bufferedWriter(stdof); + const stdout = bw.writer(); + + try stdout.print("076 coreutils\n", .{}); + try stdout.print("使用法: wc [オプション]... [ファイル]...\n", .{}); + try stdout.print("ファイル (複数可) の内容を結合して標準出力に出力します。\n", .{}); + try stdout.print("FILE が複数指定された場合は行数の合計も表示します。\n", .{}); + try stdout.print("FILE が指定されないか、 FILE が - の場合、 標準入力から読み込みます。\n", .{}); + try stdout.print("単語は、空白類文字で区切られる、長さが 0 でない表示可能文字の列です。\n\n", .{}); + try stdout.print("ファイルの指定がない場合や FILE が - の場合, 標準入力から読み込みを行います。\n\n", .{}); + try stdout.print("下記のオプションを使って、何を数えて表示するかを選択できます。\n", .{}); + try stdout.print("表示は常に次の順です: 改行数、単語数、文字数、バイト数。\n", .{}); + try stdout.print("-c バイト数を表示する\n", .{}); + try stdout.print("-m 文字数を表示する\n", .{}); + try stdout.print("-l 改行の数を表示する\n", .{}); + try stdout.print("-w 単語数を表示する\n", .{}); + try stdout.print("-h ヘルプを表示\n", .{}); + try stdout.print("-v バージョンを表示\n", .{}); + + try bw.flush(); +} + +fn ver() !void { + const stdof = io.getStdOut().writer(); + var bw = io.bufferedWriter(stdof); + const stdout = bw.writer(); + + try stdout.print("wc (076 coreutils) {s}\n", .{version}); + + try bw.flush(); +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const alloc = gpa.allocator(); + + var option = std.ArrayList(u8).init(alloc); + defer option.deinit(); + + var fname = std.ArrayList([]const u8).init(alloc); + defer fname.deinit(); + + const args = try std.process.argsAlloc(alloc); + defer std.process.argsFree(alloc, args); + + for (args, 0..) |arg, i| { + if (i == 0) continue; + var m: [1]u8 = [_]u8{'-'}; + if (std.mem.eql(u8, arg[0..1], m[0..])) { + for (arg, 0..) |a, j| { + if (j == 0) continue; + try option.append(a); + } + } else { + try fname.append(arg); + } + } + + var isbyte: bool = false; + var isline: bool = false; + var ischar: bool = false; + var isword: bool = false; + var iAmWord: bool = false; + var byte_cunt: usize = 0; + var line_cunt: usize = 0; + var char_cunt: usize = 0; + var word_cunt: usize = 0; + var byte_cuntt: usize = 0; + var line_cuntt: usize = 0; + var char_cuntt: usize = 0; + var word_cuntt: usize = 0; + + for (option.items) |i| { + if (i == 'h') { + try help(); + return; + } + if (i == 'v') { + try ver(); + return; + } + if (i == 'c') isbyte = true; + if (i == 'l') isline = true; + if (i == 'm') ischar = true; + if (i == 'w') isword = true; + } + + const stdof = io.getStdOut().writer(); + var bw = io.bufferedWriter(stdof); + const stdout = bw.writer(); + + if (isline) { + try stdout.print("改行数\tファル名\n", .{}); + } else if (isword) { + try stdout.print("単語数\tファル名\n", .{}); + } else if (ischar) { + try stdout.print("文字数\tファル名\n", .{}); + } else if (isbyte) { + try stdout.print("バイト数\tファル名\n", .{}); + } else { + try stdout.print("改行数\t単語数\t文字数\tバイト数\tファル名\n", .{}); + } + + if (fname.items.len == 0) { + // -l -c -m + const stdin = io.getStdIn().reader(); + var buf: [2048]u8 = undefined; + while (true) { + const lne = try stdin.read(buf[0..]); + if (lne == 0) { + break; + } + + const chr = try std.unicode.utf8CountCodepoints(buf[0..lne]); + line_cunt += 1; + char_cunt += chr; + byte_cunt += lne; + + // -w + for (buf[0..lne]) |char| { + if (std.ascii.isAlphanumeric(char) or char == '_' or char == '-' or char == '\'' or char == '~' or char == '&') { + if (!iAmWord) { + iAmWord = true; + word_cunt += 1; + } + } else { + iAmWord = false; + } + } + } + + if (isline) { + try stdout.print("{d}\n", .{line_cunt}); + } else if (isword) { + try stdout.print("{d}\n", .{word_cuntt}); + } else if (ischar) { + try stdout.print("{d}n", .{char_cuntt}); + } else if (isbyte) { + try stdout.print("{d}n", .{byte_cuntt}); + } else { + try stdout.print("{d}\t{d}\t{d}\t{d}\n", .{ line_cunt, word_cunt, char_cunt, byte_cunt }); + } + } else { + for (fname.items, 0..) |item, i| { + byte_cunt = 0; + line_cunt = 0; + char_cunt = 0; + word_cunt = 0; + const file = try fs.cwd().openFile(item, .{}); + defer file.close(); + + // -l -c -m + var buf: [2048]u8 = undefined; + while (true) { + const lne = try file.reader().readUntilDelimiterOrEof(buf[0..], '\n') orelse break; + const chr = try std.unicode.utf8CountCodepoints(lne); + line_cunt += 1; + char_cunt += chr; + byte_cunt += lne.len; + + // -w + for (lne) |char| { + if (std.ascii.isAlphanumeric(char) or char == '_' or char == '-' or char == '\'' or char == '~' or char == '&') { + if (!iAmWord) { + iAmWord = true; + word_cunt += 1; + } + } else { + iAmWord = false; + } + } + } + + line_cuntt += line_cunt; + char_cuntt += char_cunt; + byte_cuntt += byte_cunt; + word_cuntt += word_cunt; + + if (isline) { + try stdout.print("{d}\t{s}\n", .{ line_cunt, item }); + } else if (isword) { + try stdout.print("{d}\t{s}\n", .{ word_cuntt, item }); + } else if (ischar) { + try stdout.print("{d}\t{s}\n", .{ char_cuntt, item }); + } else if (isbyte) { + try stdout.print("{d}\t\t{s}\n", .{ byte_cuntt, item }); + } else { + try stdout.print("{d}\t{d}\t{d}\t{d}\t\t{s}\n", .{ line_cunt, word_cunt, char_cunt, byte_cunt, item }); + } + + if (i > 0) { + if (isline) { + try stdout.print("{d}\t合計\n", .{line_cuntt}); + } else if (isword) { + try stdout.print("{d}\t合計\n", .{word_cuntt}); + } else if (ischar) { + try stdout.print("{d}\t合計\n", .{char_cuntt}); + } else if (isbyte) { + try stdout.print("{d}\t\t合計\n", .{byte_cuntt}); + } else { + try stdout.print("{d}\t{d}\t{d}\t{d}\t\t合計\n", .{ line_cuntt, word_cuntt, char_cuntt, byte_cuntt }); + } + } + } + } + + try bw.flush(); +}