Skip to content

Commit a21b24e

Browse files
committed
wip
1 parent c09f57f commit a21b24e

File tree

12 files changed

+591
-21
lines changed

12 files changed

+591
-21
lines changed

src/clis/ls/main.cpp

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
1+
#include <karm-cli/args.h>
12
#include <karm-sys/dir.h>
23
#include <karm-sys/entry.h>
34

4-
Async::Task<> entryPointAsync(Sys::Context &) {
5+
Async::Task<> entryPointAsync(Sys::Context &ctx) {
6+
auto allFlag = Cli::flag('a', "all"s, "Do not ignore entries starting with ."s);
7+
auto listFlag = Cli::flag('l', "list"s, "Use a long listing format."s);
8+
9+
Cli::Command cmd{
10+
"ls"s,
11+
NONE,
12+
"List directory contents."s,
13+
{allFlag}
14+
};
15+
16+
co_trya$(cmd.execAsync(ctx));
17+
18+
if (not cmd)
19+
co_return Ok();
20+
521
auto url = co_try$(Mime::parseUrlOrPath("."));
622
auto dir = co_try$(Sys::Dir::open(url));
7-
for (auto const &entry : dir.entries())
8-
Sys::println(entry.name);
23+
24+
for (auto const &entry : dir.entries()) {
25+
if (!allFlag && entry.name[0] == '.')
26+
continue;
27+
28+
if (listFlag) {
29+
auto fileUrl = url / entry.name;
30+
auto stat = co_try$(Sys::stat(fileUrl));
31+
Sys::println("{} {} {}", stat.type == Sys::Type::DIR ? "d"s : "-"s, stat.size, stat.modifyTime, entry.name);
32+
} else {
33+
Sys::println("{}", entry.name);
34+
}
35+
}
36+
937
co_return Ok();
1038
}

src/clis/ls/manifest.json

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"type": "exe",
55
"description": "The ls coreutility",
66
"requires": [
7+
"karm-cli",
78
"karm-sys"
89
]
910
}

src/impls/impl-posix/pkg.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Res<Vec<String>> installedBundles() {
1010
auto dirs = try$(Sys::_Embed::readDir(repoRoot));
1111
Vec<String> ids;
1212
for (auto &dir : dirs) {
13-
if (dir.isDir)
13+
if (dir.type == Sys::Type::DIR)
1414
ids.pushBack(dir.name);
1515
}
1616
return Ok(ids);

src/impls/impl-posix/sys.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Res<Strong<Fd>> openFile(Mime::Url const &url) {
8787
if (raw < 0)
8888
return Posix::fromLastErrno();
8989
auto fd = makeStrong<Posix::Fd>(raw);
90-
if (try$(fd->stat()).type == Stat::DIR)
90+
if (try$(fd->stat()).type == Type::DIR)
9191
return Error::isADirectory();
9292
return Ok(fd);
9393
}
@@ -108,7 +108,7 @@ Res<Strong<Fd>> openOrCreateFile(Mime::Url const &url) {
108108
if (raw < 0)
109109
return Posix::fromLastErrno();
110110
auto fd = makeStrong<Posix::Fd>(raw);
111-
if (try$(fd->stat()).type == Stat::DIR)
111+
if (try$(fd->stat()).type == Type::DIR)
112112
return Error::isADirectory();
113113
return Ok(fd);
114114
}
@@ -164,7 +164,7 @@ Res<Vec<DirEntry>> readDir(Mime::Url const &url) {
164164

165165
entries.pushBack(DirEntry{
166166
Str::fromNullterminated(entry->d_name),
167-
entry->d_type == DT_DIR,
167+
entry->d_type == DT_DIR ? Sys::Type::DIR : Sys::Type::FILE,
168168
});
169169
}
170170

src/impls/impl-posix/utils.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ Sys::SocketAddr fromSockAddr(struct sockaddr_in sockaddr) {
214214

215215
Sys::Stat fromStat(struct stat const &buf) {
216216
Sys::Stat stat{};
217-
Sys::Stat::Type type = Sys::Stat::FILE;
217+
Sys::Type type = Sys::Type::FILE;
218218
if (S_ISDIR(buf.st_mode))
219-
type = Sys::Stat::DIR;
219+
type = Sys::Type::DIR;
220220
stat.type = type;
221221
stat.size = (usize)buf.st_size;
222222
stat.accessTime = TimeStamp::epoch() + TimeSpan::fromSecs(buf.st_atime);

src/libs/karm-cli/args.cpp

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "args.h"
2+
3+
namespace Karm::Cli {
4+
5+
// MARK: Tokenizer -------------------------------------------------------------
6+
7+
void tokenize(Str arg, Vec<Token> &out) {
8+
if (arg == "--"s) {
9+
out.pushBack(Token::EXTRA);
10+
} else if (arg == "-"s) {
11+
out.pushBack("-"s);
12+
} else if (startWith(arg, "--"s) == Match::PARTIAL) {
13+
out.emplaceBack(Token::OPTION, next(arg, 2));
14+
} else if (startWith(arg, "-"s) == Match::PARTIAL) {
15+
Str flags = next(arg, 1);
16+
for (auto r : iterRunes(flags))
17+
out.emplaceBack(r);
18+
} else {
19+
out.pushBack(arg);
20+
}
21+
}
22+
23+
void tokenize(Slice<Str> args, Vec<Token> &out) {
24+
for (auto &arg : args)
25+
tokenize(arg, out);
26+
}
27+
28+
void tokenize(int argc, char **argv, Vec<Token> &out) {
29+
for (int i = 0; i < argc; ++i)
30+
tokenize(Str::fromNullterminated(argv[i]), out);
31+
}
32+
33+
// MARK: Values ----------------------------------------------------------------
34+
35+
void ValueParser<bool>::usage(Io::Emit &e) {
36+
e("true|false");
37+
}
38+
39+
Res<bool> ValueParser<bool>::parse(Cursor<Token> &) {
40+
return Ok(true);
41+
}
42+
43+
void ValueParser<i32>::usage(Io::Emit &e) {
44+
e("integer");
45+
}
46+
47+
Res<i32> ValueParser<i32>::parse(Cursor<Token> &c) {
48+
if (c.ended() or c->kind != Token::OPERAND)
49+
return Error::other("missing value");
50+
51+
auto value = c.next().value;
52+
53+
auto result = Io::atoi(value);
54+
if (not result)
55+
return Error::other("expected integer");
56+
57+
return Ok(result.unwrap());
58+
}
59+
60+
void ValueParser<Str>::usage(Io::Emit &e) {
61+
e("string");
62+
}
63+
64+
Res<Str> ValueParser<Str>::parse(Cursor<Token> &c) {
65+
if (c.ended() or c->kind != Token::OPERAND)
66+
return Error::other("missing value");
67+
68+
return Ok(c.next().value);
69+
}
70+
71+
} // namespace Karm::Cli

0 commit comments

Comments
 (0)