Skip to content

Commit f923286

Browse files
committed
2026-06-07
1 parent 3edbaa9 commit f923286

17 files changed

Lines changed: 402 additions & 435 deletions

File tree

bin/cptest.rs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ fn find_source_file() -> Result<String, String> {
6666
Err("Error: No source file found".to_string())
6767
}
6868

69-
fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
69+
fn compile_file(filepath: &str, contest_compilation: bool) -> Result<(), String> {
7070
let path = Path::new(filepath);
7171
let ext = path.extension().and_then(|s| s.to_str()).unwrap_or("");
7272
let exe_name = path.file_stem().and_then(|s| s.to_str()).unwrap_or("a.out");
7373

7474
match ext {
7575
"ml" => {
7676
let mut args = vec!["-o", exe_name, filepath];
77-
if debug {
77+
if !contest_compilation {
7878
args.insert(0, "-g");
7979
}
8080
let status = Command::new("ocamlopt")
@@ -90,12 +90,17 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
9090
}
9191
"cpp" => {
9292
let mut args = vec!["-x", "c++", "-std=gnu++20"];
93-
if debug {
94-
args.push("-g");
95-
args.push("-fsanitize=address,undefined");
96-
} else {
93+
if contest_compilation {
9794
args.push("-O2");
9895
args.push("-static");
96+
} else {
97+
args.append(&mut vec!["-Wall", "-Wextra", "-Wshadow", "-Wfloat-equal", "-Wconversion", "-Wlogical-op", "-Wshift-overflow=2", "-Wduplicated-cond", "-Wfatal-errors"]);
98+
args.append(&mut vec!["-DISDEBUG", "-D_GLIBCXX_DEBUG"]);
99+
args.append(&mut vec!["-fsanitize=undefined,address", "-fstack-protector", "-fno-sanitize-recover"]);
100+
args.push("-g3");
101+
args.push("-fsanitize=address,undefined");
102+
args.push("-DISDEBUG");
103+
99104
}
100105
args.push(filepath);
101106
args.push("-o");
@@ -123,7 +128,7 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
123128
"-d",
124129
".",
125130
];
126-
if debug {
131+
if !contest_compilation {
127132
args.push("-g");
128133
}
129134
args.push(filepath);
@@ -144,23 +149,23 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
144149
}
145150
}
146151

147-
fn find_test_files() -> Vec<(String, String)> {
152+
fn find_test_files() -> Vec<(String, Option<String>)> {
148153
let mut tests = Vec::new();
149154

150155
if let Ok(entries) = fs::read_dir(".") {
151156
let mut inputs: Vec<String> = entries
152157
.filter_map(|entry| entry.ok())
153158
.map(|entry| entry.file_name().to_string_lossy().to_string())
154-
.filter(|name| name.starts_with("~input") && name.ends_with(".txt"))
159+
.filter(|name| name.starts_with("in") && name[2..].chars().next().map_or(false, |c| c.is_ascii_digit()))
155160
.collect();
156161

157162
inputs.sort();
158163

159164
for input in inputs {
160-
let output = input.replace("~input", "~output");
161-
if Path::new(&output).exists() {
162-
tests.push((input, output));
163-
}
165+
let suffix = &input[2..];
166+
let output = format!("out{}", suffix);
167+
let output_opt = if Path::new(&output).exists() { Some(output) } else { None };
168+
tests.push((input, output_opt));
164169
}
165170
}
166171

@@ -176,7 +181,7 @@ fn run_tests(filepath: &str) -> Result<(), String> {
176181
let tests = find_test_files();
177182

178183
if tests.is_empty() {
179-
println!("No test files found (looking for ~input*.txt and ~output*.txt)");
184+
println!("No test files found (looking for in1, in2, ... files)");
180185
return Ok(());
181186
}
182187

@@ -186,12 +191,14 @@ fn run_tests(filepath: &str) -> Result<(), String> {
186191
if tests.len() == 1 { "test" } else { "tests" }
187192
);
188193
for (test_num, (input_file, output_file)) in tests.iter().enumerate() {
189-
println!("\x1B[1mTEST {}\x1B[0m", test_num + 1);
194+
println!("\x1B[1;4mTEST {}\x1B[0m", test_num + 1);
190195

191196
let input_data =
192197
fs::read(&input_file).map_err(|e| format!("Failed to read {}: {}", input_file, e))?;
193-
let expected_output = fs::read_to_string(&output_file)
194-
.map_err(|e| format!("Failed to read {}: {}", output_file, e))?;
198+
let expected_output: Option<String> = match output_file {
199+
Some(f) => Some(fs::read_to_string(f).map_err(|e| format!("Failed to read {}: {}", f, e))?),
200+
None => None,
201+
};
195202

196203
let output = match ext {
197204
"ml" | "cpp" => {
@@ -270,14 +277,17 @@ fn run_tests(filepath: &str) -> Result<(), String> {
270277
io::stdout().flush().unwrap();
271278

272279
let trimmed_output = output.trim_end();
273-
println!("--- \x1b[3mExpected\x1b[0m");
274-
println!("{}", expected_output.trim_end());
275280
println!("--- \x1b[3mActual\x1b[0m");
276281
if trimmed_output.is_empty() {
277282
println!("\x1b[3mN/A\x1b[0m");
278283
} else {
279284
println!("{}", trimmed_output);
280285
}
286+
println!("--- \x1b[3mExpected\x1b[0m");
287+
match &expected_output {
288+
Some(expected) => println!("{}", expected.trim_end()),
289+
None => println!("\x1b[3mN/A\x1b[0m"),
290+
}
281291
println!("---");
282292

283293
if test_num != tests.len() - 1 {
@@ -292,15 +302,15 @@ fn main() {
292302
let args: Vec<String> = env::args().collect();
293303
let mut test = false;
294304
let mut execute = false;
295-
let mut debug = false;
305+
let mut contest = false;
296306
let mut filepath: Option<String> = None;
297307
for arg in args.iter().skip(1) {
298308
match arg.as_str() {
299309
"-h" => {
300310
println!("Usage: cptest [OPTIONS] [FILE]");
301311
println!();
302312
println!("OPTIONS:");
303-
println!(" -d Compile with debug flags");
313+
println!(" -c Contest compilation");
304314
println!(" -t Run all tests");
305315
println!(" -x Execute the compiled program");
306316
println!(" -h Show this help message");
@@ -312,7 +322,7 @@ fn main() {
312322
}
313323
"-t" => test = true,
314324
"-x" => execute = true,
315-
"-d" => debug = true,
325+
"-c" => contest = true,
316326
s if !s.starts_with('-') => {
317327
if filepath.is_none() {
318328
filepath = Some(s.to_string());
@@ -348,7 +358,7 @@ fn main() {
348358
}
349359

350360
println!("Compiling {}", filepath);
351-
if let Err(e) = compile_file(&filepath, debug) {
361+
if let Err(e) = compile_file(&filepath, contest) {
352362
eprintln!("{}", e);
353363
exit(1);
354364
}

config-application/.local/share/albert/python/plugins/hyperupcall-binaries/__init__.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
import os
55
from albert import *
66

7-
md_iid = "2.1"
8-
md_version = "1.0"
7+
md_iid = '2.1'
8+
md_version = '1.0'
99
md_name = "Edwin's Binaries"
1010
md_description = "Launch Edwin's binaries"
1111
# md_bin_dependencies = ["pass"]
12-
md_maintainers = ["@hyperupcall"]
13-
md_license = "MPL-2.0"
12+
md_maintainers = ['@hyperupcall']
13+
md_license = 'MPL-2.0'
1414

15-
HOME_DIR = os.environ["HOME"]
16-
PASS_DIR = os.environ.get("PASSWORD_STORE_DIR", os.path.join(HOME_DIR, ".password-store/"))
15+
HOME_DIR = os.environ['HOME']
16+
PASS_DIR = os.environ.get(
17+
'PASSWORD_STORE_DIR', os.path.join(HOME_DIR, '.password-store/')
18+
)
1719

1820

1921
class Plugin(PluginInstance, TriggerQueryHandler):
@@ -23,11 +25,11 @@ def __init__(self):
2325
id=md_id,
2426
name=md_name,
2527
description=md_description,
26-
synopsis="<pass-name>",
27-
defaultTrigger="run ",
28+
synopsis='<pass-name>',
29+
defaultTrigger='run ',
2830
)
2931
PluginInstance.__init__(self, extensions=[self])
30-
self.iconUrls = ["xdg:dialog-password"]
32+
self.iconUrls = ['xdg:dialog-password']
3133
self._some_path = ''
3234

3335
@property
@@ -36,36 +38,36 @@ def some_path(self):
3638

3739
@some_path.setter
3840
def some_path(self, value):
39-
print(f"Setting _some_path to {value}")
41+
print(f'Setting _some_path to {value}')
4042
self._some_path = value
41-
self.writeConfig("some_path", value)
43+
self.writeConfig('some_path', value)
4244

4345
def configWidget(self):
4446
return [
4547
{
46-
"type": "lineedit",
47-
"property": "some_path",
48-
"label": "Some path for testing",
49-
"widget_properties": {"placeholderText": "this is epic"},
48+
'type': 'lineedit',
49+
'property': 'some_path',
50+
'label': 'Some path for testing',
51+
'widget_properties': {'placeholderText': 'this is epic'},
5052
},
5153
]
5254

5355
def handleTriggerQuery(self, query):
54-
apps = {
55-
'default': ''
56-
}
56+
apps = {'default': ''}
5757
query.add(
5858
StandardItem(
59-
id="launch_hub",
59+
id='launch_hub',
6060
iconUrls=self.iconUrls,
61-
text="Launch hub.woof",
62-
subtext="Launch hub.woof site in a browser",
63-
inputActionText="e hub",
61+
text='Launch hub.woof',
62+
subtext='Launch hub.woof site in a browser',
63+
inputActionText='e hub',
6464
actions=[
6565
Action(
66-
"hub",
67-
"hub.woof",
68-
lambda: runDetachedProcess(["xdg-open", "http://localhost:49501"]),
66+
'hub',
67+
'hub.woof',
68+
lambda: runDetachedProcess(
69+
['xdg-open', 'http://localhost:49501']
70+
),
6971
)
7072
],
7173
)

config-application/.local/share/albert/python/plugins/hyperupcall-code/__init__.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
from albert import *
66
from pathlib import Path
77

8-
md_iid = "2.1"
9-
md_version = "1.0"
8+
md_iid = '2.1'
9+
md_version = '1.0'
1010
md_name = "Edwin's Coding Start"
11-
md_description = "Start an IDE session for a coding project."
12-
md_bin_dependencies = ["code"]
13-
md_maintainers = ["@hyperupcall"]
14-
md_license = "MPL-2.0"
11+
md_description = 'Start an IDE session for a coding project.'
12+
md_bin_dependencies = ['code']
13+
md_maintainers = ['@hyperupcall']
14+
md_license = 'MPL-2.0'
15+
1516

1617
class Plugin(PluginInstance, TriggerQueryHandler):
1718
def __init__(self):
@@ -20,45 +21,47 @@ def __init__(self):
2021
id=md_id,
2122
name=md_name,
2223
description=md_description,
23-
synopsis="<project-name>",
24-
defaultTrigger="code ",
24+
synopsis='<project-name>',
25+
defaultTrigger='code ',
2526
)
2627
PluginInstance.__init__(self, extensions=[self])
27-
self.iconUrls = ["xdg:dialog-password"]
28-
self._editor = self.readConfig("editor", str) or 'code'
28+
self.iconUrls = ['xdg:dialog-password']
29+
self._editor = self.readConfig('editor', str) or 'code'
2930

3031
@property
3132
def editor(self):
3233
return self._editor
3334

3435
@editor.setter
3536
def editor(self, value):
36-
print(f"Setting _use_otp to {value}")
37+
print(f'Setting _use_otp to {value}')
3738
self._editor = value
38-
self.writeConfig("use_otp", value)
39+
self.writeConfig('use_otp', value)
3940

4041
def configWidget(self):
4142
return [
4243
{
43-
"type": "lineedit",
44-
"property": "editor",
45-
"label": "Editor to execute.",
46-
"widget_properties": {"placeholderText": "code"},
44+
'type': 'lineedit',
45+
'property': 'editor',
46+
'label': 'Editor to execute.',
47+
'widget_properties': {'placeholderText': 'code'},
4748
},
4849
]
4950

5051
def handleTriggerQuery(self, query):
51-
org_dir = os.path.expanduser("~/.home/Documents/Projects/Programming/Organizations")
52+
org_dir = os.path.expanduser(
53+
'~/.home/Documents/Projects/Programming/Organizations'
54+
)
5255

5356
paths = []
5457
if query.string.strip():
55-
for path in Path(org_dir).glob("*/*/"):
58+
for path in Path(org_dir).glob('*/*/'):
5659
owner = path.parts[-2]
5760
project = path.parts[-1]
5861
if (query.string in owner) or (query.string in project):
5962
paths.append(f'{owner}/{project}')
6063
else:
61-
for path in Path(org_dir).glob("*/*/"):
64+
for path in Path(org_dir).glob('*/*/'):
6265
owner = path.parts[-2]
6366
project = path.parts[-1]
6467
paths.append(f'{owner}/{project}')
@@ -73,15 +76,17 @@ def handleTriggerQuery(self, query):
7376
full_dir = os.path.join(org_dir, dir)
7477
results.append(
7578
StandardItem(
76-
id=f"{owner}_{project}",
79+
id=f'{owner}_{project}',
7780
iconUrls=self.iconUrls,
78-
text=f"{owner}/{project}",
79-
inputActionText=f"{owner}/{project}",
81+
text=f'{owner}/{project}',
82+
inputActionText=f'{owner}/{project}',
8083
actions=[
8184
Action(
8285
'Launch',
8386
'Do in launch',
84-
lambda full_dir=str(full_dir): runDetachedProcess([self.editor, full_dir]),
87+
lambda full_dir=str(full_dir): runDetachedProcess(
88+
[self.editor, full_dir]
89+
),
8590
)
8691
],
8792
)

0 commit comments

Comments
 (0)