Skip to content

Commit 6649256

Browse files
committed
Add missing core subpackage (renamed from lib)
The `lib` package was completely nonexistent as I overlooked the fact that it was gitignore'd. This has been fixed by renaming it to `core`.
1 parent 1018d2f commit 6649256

30 files changed

+145
-81
lines changed

userland/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .command import *
2+
from .io import *

userland/core/command.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import sys
2+
from optparse import OptionParser
3+
from typing import Any, Callable
4+
5+
6+
def create_parser(usage: tuple[str], **kwargs) -> OptionParser:
7+
if parser_class := kwargs.get("parser_class"):
8+
del kwargs["parser_class"]
9+
10+
parser = (parser_class or OptionParser)(
11+
usage="Usage: " + f"\n{7 * " "}".join(usage),
12+
**kwargs,
13+
add_help_option=False,
14+
)
15+
parser.add_option(
16+
"--help",
17+
action="help",
18+
help="show usage information and exit",
19+
)
20+
21+
return parser
22+
23+
24+
def command(parser: OptionParser | None = None):
25+
def create_utility(
26+
func: Callable[[dict[str, Any], list[Any]], int],
27+
) -> Callable[[], None]:
28+
if parser:
29+
30+
def execute_utility():
31+
sys.exit(func(*parser.parse_args()))
32+
33+
else:
34+
35+
def execute_utility():
36+
sys.exit(func({}, sys.argv[1:]))
37+
38+
return execute_utility
39+
40+
return create_utility

userland/core/io.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import sys
2+
from typing import Generator
3+
4+
5+
def readlines_stdin() -> Generator[str]:
6+
while line := sys.stdin.readline():
7+
yield line
8+
9+
10+
def readlines_stdin_raw() -> Generator[bytes]:
11+
while line := sys.stdin.buffer.readline():
12+
yield line
13+
14+
15+
def readwords_stdin() -> Generator[str]:
16+
for line in readlines_stdin():
17+
yield from line.split()
18+
19+
20+
def readwords_stdin_raw() -> Generator[bytes]:
21+
for line in readlines_stdin_raw():
22+
yield from line.split()

userland/utilities/basename.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
from pathlib import PurePath
44

5-
from .. import lib
5+
from .. import core
66

7-
parser = lib.create_parser(
7+
parser = core.create_parser(
88
usage=("%prog NAME [SUFFIX]", "%prog OPTION... NAME..."),
99
description="Print the last component of each path NAME.",
1010
)
@@ -26,7 +26,7 @@
2626
)
2727

2828

29-
@lib.command(parser)
29+
@core.command(parser)
3030
def python_userland_basename(opts, args):
3131
if not args:
3232
parser.error("missing operand")

userland/utilities/cat.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from io import BufferedReader
66
from typing import BinaryIO, Generator
77

8-
from .. import lib
8+
from .. import core
99

1010

1111
def squeeze_blank_lines(io: BinaryIO) -> Generator[bytes]:
@@ -96,7 +96,7 @@ def cat_io(opts, io: BinaryIO) -> None:
9696
sys.stdout.buffer.flush()
9797

9898

99-
parser = lib.create_parser(
99+
parser = core.create_parser(
100100
usage=("%prog [OPTION]... [FILE]...",),
101101
description="Concatenate each FILE to standard output.",
102102
)
@@ -135,7 +135,7 @@ def cat_io(opts, io: BinaryIO) -> None:
135135
)
136136

137137

138-
@lib.command(parser)
138+
@core.command(parser)
139139
def python_userland_cat(opts, args):
140140
if opts.show_all:
141141
opts.show_ends = True
@@ -149,7 +149,7 @@ def python_userland_cat(opts, args):
149149
opts.show_nonprinting = True
150150

151151
generators = [
152-
lib.readlines_stdin_raw() if name == "-" else open(name, "rb")
152+
core.readlines_stdin_raw() if name == "-" else open(name, "rb")
153153
for name in args or ["-"]
154154
]
155155

userland/utilities/clear.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#!/usr/bin/python3
22

3-
from .. import lib
3+
from .. import core
44

55
# clear(1), roughly modelled off the ncurses implementation.
66

77

8-
parser = lib.create_parser(
8+
parser = core.create_parser(
99
usage=("%prog [OPTION]...",),
1010
description="Clear the terminal screen.",
1111
)
@@ -17,7 +17,7 @@
1717
)
1818

1919

20-
@lib.command(parser)
20+
@core.command(parser)
2121
def python_userland_clear(opts, args):
2222
if args:
2323
return 1

userland/utilities/dirname.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
from pathlib import PurePath
44

5-
from .. import lib
5+
from .. import core
66

7-
parser = lib.create_parser(
7+
parser = core.create_parser(
88
usage=("%prog [OPTION]... NAME...",),
99
description=(
1010
"Print each path NAME with the last component removed,"
@@ -21,7 +21,7 @@
2121
)
2222

2323

24-
@lib.command(parser)
24+
@core.command(parser)
2525
def python_userland_dirname(opts, args):
2626
if not args:
2727
parser.error("missing operand")

userland/utilities/echo.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import re
55
from optparse import OptionParser, BadOptionError, AmbiguousOptionError
66

7-
from .. import lib
7+
from .. import core
88

99
ESCAPES_PATTERN = re.compile(
1010
r"(\\0[0-7]{1,3}|\\x[0-9A-Za-z]{1,2}|\\[\\0abcefnrtv])",
@@ -35,7 +35,7 @@ def _process_args(self, largs, rargs, values):
3535
rargs.clear()
3636

3737

38-
parser = lib.create_parser(
38+
parser = core.create_parser(
3939
usage=("%prog [OPTION]... [STRING]...",),
4040
description="Print STRING(s) to standard output.",
4141
parser_class=PassthroughOptionParser,
@@ -58,7 +58,7 @@ def _process_args(self, largs, rargs, values):
5858
)
5959

6060

61-
@lib.command(parser)
61+
@core.command(parser)
6262
def python_userland_echo(opts, args):
6363
string = " ".join(args)
6464

userland/utilities/factor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sys
55
from typing import Generator, Iterable
66

7-
from .. import lib
7+
from .. import core
88

99
# List of small primes greater than 2; used for lookup.
1010
SMALL_PRIMES = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
@@ -101,20 +101,20 @@ def format_exponents(factors: Iterable[int]) -> str:
101101
return " ".join(processed)
102102

103103

104-
parser = lib.create_parser(
104+
parser = core.create_parser(
105105
usage=("%prog [OPTION] [NUMBER]...",),
106106
description="Compute and print the prime factors of each positive integer NUMBER.",
107107
)
108108

109109
parser.add_option("-h", "--exponents", action="store_true")
110110

111111

112-
@lib.command(parser)
112+
@core.command(parser)
113113
def python_userland_factor(opts, args):
114114
failed = False
115115

116116
try:
117-
for arg in args or lib.readwords_stdin():
117+
for arg in args or core.readwords_stdin():
118118
try:
119119
num = int(arg)
120120
if num < 0:

userland/utilities/false.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import os
44
import sys
55

6-
from .. import lib
6+
from .. import core
77

88

9-
@lib.command()
9+
@core.command()
1010
def python_userland_false(_, args):
1111
if args and args[0] == "--help":
1212
print(

userland/utilities/groups.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
import os
66
import sys
77

8-
from .. import lib
8+
from .. import core
99

10-
parser = lib.create_parser(
10+
parser = core.create_parser(
1111
usage=("%prog [USERNAME]...",),
1212
description="Print a list of groups for each USERNAME or the current user.",
1313
)
1414

1515

16-
@lib.command(parser)
16+
@core.command(parser)
1717
def python_userland_groups(_, args):
1818
failed = False
1919

userland/utilities/hostid.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#!/usr/bin/python3
22

3-
from .. import lib
3+
from .. import core
44

5-
parser = lib.create_parser(
5+
parser = core.create_parser(
66
usage=("%prog",),
77
description="Print a 32-bit numeric host machine identifier.",
88
epilog="This implementation gives an all-zero identifier.",
99
)
1010

1111

12-
@lib.command(parser)
12+
@core.command(parser)
1313
def python_userland_hostid(_, args):
1414
if args:
1515
parser.error(f"extra operand '{args[0]}'")

userland/utilities/id.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import os
66
import sys
77

8-
from .. import lib
8+
from .. import core
99

10-
parser = lib.create_parser(
10+
parser = core.create_parser(
1111
usage=("%prog [OPTION]... [USER]...",),
1212
description="Print user and group information for each USER or the current user.",
1313
)
@@ -45,7 +45,7 @@
4545
parser.add_option("-Z", "--context", action="store_true", help="(unimplemented)")
4646

4747

48-
@lib.command(parser)
48+
@core.command(parser)
4949
def python_userland_id(opts, args):
5050
if opts.context:
5151
parser.error("--context (-Z) is not supported")

userland/utilities/logname.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
import os
44

5-
from .. import lib
5+
from .. import core
66

7-
parser = lib.create_parser(
7+
parser = core.create_parser(
88
usage=("%prog",),
99
description="Print the current user's login name.",
1010
)
1111

1212

13-
@lib.command(parser)
13+
@core.command(parser)
1414
def python_userland_logname(_, args):
1515
if args:
1616
parser.error(f"extra operand '{args[0]}'")

userland/utilities/nologin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/python3
22

3-
from .. import lib
3+
from .. import core
44

5-
parser = lib.create_parser(
5+
parser = core.create_parser(
66
usage=("%prog",),
77
description="Politely refuse a login.",
88
)
99

1010

11-
@lib.command(parser)
11+
@core.command(parser)
1212
def python_userland_nologin(*_):
1313
print("This account is currently not available.")
1414
return 1

userland/utilities/nproc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import os
44

55

6-
from .. import lib
6+
from .. import core
77

8-
parser = lib.create_parser(
8+
parser = core.create_parser(
99
usage=(" %prog [OPTION]...",),
1010
description="Print the number of processing units available to the process.",
1111
)
@@ -25,7 +25,7 @@
2525
)
2626

2727

28-
@lib.command(parser)
28+
@core.command(parser)
2929
def python_userland_nproc(opts, args):
3030
if args:
3131
parser.error(f"extra operand '{args[0]}'")

userland/utilities/printenv.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
import os
44

5-
from .. import lib
5+
from .. import core
66

7-
parser = lib.create_parser(
7+
parser = core.create_parser(
88
usage=(" %prog [OPTION] [VARIABLE]...",),
99
description="Print VARIABLE(s) or all environment variables, and their values.",
1010
)
1111

1212
parser.add_option("-0", "--null", action="store_true")
1313

1414

15-
@lib.command(parser)
15+
@core.command(parser)
1616
def python_userland_printenv(opts, var_names: list[str]):
1717
endchar = "\0" if opts.null else "\n"
1818

userland/utilities/pwd.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import os
44

5-
from .. import lib
5+
from .. import core
66

7-
parser = lib.create_parser(
7+
parser = core.create_parser(
88
usage=("%prog [OPTION]",),
99
description="Print the path to the current working directory.",
1010
)
@@ -26,7 +26,7 @@
2626
)
2727

2828

29-
@lib.command(parser)
29+
@core.command(parser)
3030
def python_userland_pwd(opts, args):
3131
if args:
3232
parser.error("too many arguments")

0 commit comments

Comments
 (0)