lang migration: rename signed integer types sN -> iN

Mechanical sweep of all .sx sources and plan docs (PLAN.md, current/,
.agents/) for the sx language rename (s8/s16/s32/s64 -> i8/i16/i32/i64).
Verified: make build + make test, 14/14.
This commit is contained in:
agra
2026-06-12 09:39:49 +03:00
parent cf39589798
commit 6c19f1073f
30 changed files with 75 additions and 75 deletions

View File

@@ -35,7 +35,7 @@ srv :: #import "server/distd.sx";
// Direct stderr writer (fd 2), so human help/usage/progress never lands on
// stdout's data stream. `out` (std builtin) targets stdout (fd 1).
cstdlib :: #library "c";
fd_write :: (fd: s32, buf: [*]u8, count: usize) -> isize #foreign cstdlib "write";
fd_write :: (fd: i32, buf: [*]u8, count: usize) -> isize #foreign cstdlib "write";
eputs :: (s: string) { if s.len > 0 { fd_write(2, s.ptr, xx s.len); } }
@@ -187,7 +187,7 @@ handle_release_rollback :: (p: *Parsed, json_mode: bool) {
// `report_failure` like every other command.
handle_server_run :: (p: *Parsed, json_mode: bool) {
store_dir := p.value_of("local-store");
port : s64 = 8787;
port : i64 = 8787;
if p.is_set("port") {
pq := parse_port(p.value_of("port"));
if pq == null {
@@ -210,9 +210,9 @@ handle_server_run :: (p: *Parsed, json_mode: bool) {
// Decimal port in 1..65535; anything else (empty, non-digits, out of
// range) is null — a usage error at the call site.
parse_port :: (s: string) -> ?s64 {
parse_port :: (s: string) -> ?i64 {
if s.len == 0 or s.len > 5 { return null; }
v : s64 = 0;
v : i64 = 0;
i := 0;
while i < s.len {
c := s[i];

View File

@@ -26,6 +26,6 @@ App :: struct {
bundle_ids: List(BundleId);
owner: string;
visibility: Visibility = .private;
created_at: s64;
updated_at: s64;
created_at: i64;
updated_at: i64;
}

View File

@@ -20,7 +20,7 @@ Artifact :: struct {
platform: Platform;
filename: string;
content_type: string;
size_bytes: s64;
size_bytes: i64;
sha256: string;
storage_key: string;
metadata: string;

View File

@@ -11,5 +11,5 @@ AuditEvent :: struct {
target_type: string;
target_id: string;
metadata: string;
created_at: s64;
created_at: i64;
}

View File

@@ -15,5 +15,5 @@ Channel :: struct {
name: string;
current_release_id: string;
policy: RolloutPolicy = .manual;
rollout_percent: s64 = 100;
rollout_percent: i64 = 100;
}

View File

@@ -8,10 +8,10 @@ Release :: struct {
id: string;
app_id: string;
version: string;
build: s64;
build: i64;
channel: string;
notes: string;
created_by: string;
created_at: s64;
published_at: s64;
created_at: i64;
published_at: i64;
}

View File

@@ -23,7 +23,7 @@ CliFailure :: struct {
// "error": { "code": <code>, "message": <message> } }` — into the
// caller-owned `dst`, returning the bytes written. Overflow surfaces on
// the error channel.
write_error :: (f: CliFailure, dst: []u8) -> (s64, !JsonError) {
write_error :: (f: CliFailure, dst: []u8) -> (i64, !JsonError) {
gpa := GPA.init();
obj : Object = .{};
obj.put("status", .str("error"), xx gpa);

View File

@@ -65,7 +65,7 @@ ManifestArtifact :: struct {
filename: string;
content_type: string;
metadata: string;
size: s64 = -1;
size: i64 = -1;
sha256: string = "";
}
@@ -121,7 +121,7 @@ opt_str :: (o: Object, key: string, alloc: Allocator) -> (string, !ManifestErr)
// Optional integer field. Absent -> `default` (a documented default, not a
// silent one); present-but-not-an-integer -> WrongType.
opt_int :: (o: Object, key: string, default: s64) -> (s64, !ManifestErr) {
opt_int :: (o: Object, key: string, default: i64) -> (i64, !ManifestErr) {
v := obj_find(o, key);
if v == null { return default; }
val := v!;

View File

@@ -57,7 +57,7 @@ jout :: #import "../json_out.sx";
// time stamped onto the release / audit events, and the process cwd used to
// absolutize a relative `--local-store` into the download URL.
cstd :: #library "c";
c_time :: (tloc: *s64) -> s64 #foreign cstd "time";
c_time :: (tloc: *i64) -> i64 #foreign cstd "time";
c_getcwd :: (buf: [*]u8, size: usize) -> *u8 #foreign cstd "getcwd";
// Failure classes for the publish pipeline. One distinct tag per stage so
@@ -80,7 +80,7 @@ PublishError :: error {
PublishedArtifact :: struct {
id: string;
platform_name: string;
size_bytes: s64;
size_bytes: i64;
sha256: string;
url: string;
}
@@ -99,8 +99,8 @@ PublishOutcome :: struct {
// Current wall-clock time as unix epoch seconds (time(2) via a local slot,
// so no null pointer is needed).
now_secs :: () -> s64 {
t : s64 = 0;
now_secs :: () -> i64 {
t : i64 = 0;
return c_time(@t);
}
@@ -111,7 +111,7 @@ abs_store :: (dir: string) -> string {
if dir.len > 0 and dir[0] == 47 { return dir; } // 47='/' already absolute
buf : [4096]u8 = ---;
r := c_getcwd(@buf[0], 4096);
if cast(s64) r == 0 { return dir; }
if cast(i64) r == 0 { return dir; }
n := 0;
while buf[n] != 0 { n += 1; }
cwd := string.{ ptr = @buf[0], len = n };
@@ -360,7 +360,7 @@ run_publish :: (manifest_path: string, store_dir: string, fail_out: *jout.CliFai
// release{id,app_id,version,channel}, artifacts[]{id,platform,size_bytes,
// sha256,url}) by `std.json`'s insertion-order guarantee. Overflow surfaces
// on the error channel.
write_json :: (o: *PublishOutcome, dst: []u8) -> (s64, !JsonError) {
write_json :: (o: *PublishOutcome, dst: []u8) -> (i64, !JsonError) {
gpa := GPA.init();
root : Object = .{};
root.put("status", .str("published"), xx gpa);

View File

@@ -245,7 +245,7 @@ run_rollback :: (store_dir: string, app_slug: string, channel_name: string, fail
// `{"status":"promoted","app_id":...,"channel":...,"release":{"id":...,
// "version":...},"previous_release_id":...}` — member order fixed by
// `std.json`'s insertion-order guarantee.
write_promote_json :: (o: *PromoteOutcome, dst: []u8) -> (s64, !JsonError) {
write_promote_json :: (o: *PromoteOutcome, dst: []u8) -> (i64, !JsonError) {
gpa := GPA.init();
root : Object = .{};
root.put("status", .str("promoted"), xx gpa);
@@ -263,7 +263,7 @@ write_promote_json :: (o: *PromoteOutcome, dst: []u8) -> (s64, !JsonError) {
// `{"status":"rolled_back","app_id":...,"channel":...,"from_release_id":...,
// "to":{"id":...,"version":...}}`.
write_rollback_json :: (o: *RollbackOutcome, dst: []u8) -> (s64, !JsonError) {
write_rollback_json :: (o: *RollbackOutcome, dst: []u8) -> (i64, !JsonError) {
gpa := GPA.init();
root : Object = .{};
root.put("status", .str("rolled_back"), xx gpa);

View File

@@ -271,7 +271,7 @@ req_str_view :: (o: Object, key: string) -> (string, !LoadErr) {
return val.str;
}
req_int :: (o: Object, key: string) -> (s64, !LoadErr) {
req_int :: (o: Object, key: string) -> (i64, !LoadErr) {
v := db_obj_find(o, key);
if v == null { raise error.BadShape; }
val := v!;

View File

@@ -146,7 +146,7 @@ Repo :: struct {
self.channels.append(c, self.own_allocator);
}
// Channels are keyed by (app_id, name) — there is no separate id.
channel_index :: (self: *Repo, app_id: string, name: string) -> s64 {
channel_index :: (self: *Repo, app_id: string, name: string) -> i64 {
i := 0;
while i < self.channels.len {
c := self.channels.items[i];

View File

@@ -96,7 +96,7 @@ render_buf :: () -> string {
// ── responses ─────────────────────────────────────────────────────────
// JSON error body in the CLI's error shape, sent with the HTTP status.
respond_error :: (client: s32, code: s64, fail_code: string, fail_message: string) {
respond_error :: (client: i32, code: i64, fail_code: string, fail_message: string) {
f : jout.CliFailure = .{ code = fail_code, message = fail_message };
raw : [4096]u8 = ---;
werr := false;
@@ -110,7 +110,7 @@ respond_error :: (client: s32, code: s64, fail_code: string, fail_message: strin
// Reload the persisted model. Null means the store has no readable
// db.json — the 503 error response has already been sent.
load_or_503 :: (client: s32, store_dir: string) -> ?Repo {
load_or_503 :: (client: i32, store_dir: string) -> ?Repo {
if !exists(path_join(store_dir, "db.json")) {
respond_error(client, 503, "store.load",
concat("no db.json under the store (nothing published yet): ", store_dir));
@@ -126,7 +126,7 @@ load_or_503 :: (client: s32, store_dir: string) -> ?Repo {
}
// `{"apps":[...]}` into `dst`, returning the bytes written.
render_apps_json :: (repo: *Repo, dst: []u8) -> (s64, !JsonError) {
render_apps_json :: (repo: *Repo, dst: []u8) -> (i64, !JsonError) {
alloc := context.allocator;
root : Object = .{};
arr : Array = .{};
@@ -142,7 +142,7 @@ render_apps_json :: (repo: *Repo, dst: []u8) -> (s64, !JsonError) {
}
// `{"app":..,"releases":[..],"channels":[..]}` for `app` into `dst`.
render_app_detail_json :: (repo: *Repo, app: App, dst: []u8) -> (s64, !JsonError) {
render_app_detail_json :: (repo: *Repo, app: App, dst: []u8) -> (i64, !JsonError) {
alloc := context.allocator;
root : Object = .{};
root.put("app", db.app_to_json(app, alloc), alloc);
@@ -172,7 +172,7 @@ render_app_detail_json :: (repo: *Repo, app: App, dst: []u8) -> (s64, !JsonError
// Send `n` rendered bytes of `buf` as 200 JSON — or the overflow error
// when the render didn't fit RENDER_CAP.
respond_render :: (client: s32, buf: string, n: s64, overflowed: bool) {
respond_render :: (client: i32, buf: string, n: i64, overflowed: bool) {
if overflowed {
respond_error(client, 500, "http.response_overflow",
"response exceeded the server's render buffer");
@@ -271,7 +271,7 @@ render_index :: (repo: *Repo) -> string {
return concat(page, INDEX_FOOT);
}
handle_index :: (client: s32, store_dir: string) {
handle_index :: (client: i32, store_dir: string) {
rq := load_or_503(client, store_dir);
if rq == null { return; }
repo := rq!;
@@ -280,7 +280,7 @@ handle_index :: (client: s32, store_dir: string) {
// ── routes ────────────────────────────────────────────────────────────
handle_apps_index :: (client: s32, store_dir: string) {
handle_apps_index :: (client: i32, store_dir: string) {
rq := load_or_503(client, store_dir);
if rq == null { return; }
repo := rq!;
@@ -291,7 +291,7 @@ handle_apps_index :: (client: s32, store_dir: string) {
respond_render(client, buf, n, werr);
}
handle_app_detail :: (client: s32, store_dir: string, slug: string) {
handle_app_detail :: (client: i32, store_dir: string, slug: string) {
rq := load_or_503(client, store_dir);
if rq == null { return; }
repo := rq!;
@@ -309,7 +309,7 @@ handle_app_detail :: (client: s32, store_dir: string, slug: string) {
respond_render(client, buf, n, werr);
}
handle_download :: (client: s32, store_dir: string, sha: string) {
handle_download :: (client: i32, store_dir: string, sha: string) {
if !is_hex64(sha) {
respond_error(client, 404, "download.bad_key",
"download key must be a 64-char lowercase-hex sha256");
@@ -327,7 +327,7 @@ handle_download :: (client: s32, store_dir: string, sha: string) {
}
// Route one parsed request. GET only; the path decides the handler.
route :: (client: s32, store_dir: string, method: string, path: string) -> s64 {
route :: (client: i32, store_dir: string, method: string, path: string) -> i64 {
if method != "GET" {
respond_error(client, 405, "http.method_not_allowed",
"every distd route is GET for now (writes go through the dist CLI)");
@@ -362,7 +362,7 @@ route :: (client: s32, store_dir: string, method: string, path: string) -> s64 {
// Read one request off `client`, route it, log the result line. All
// allocations land in the pushed per-request context allocator.
serve_one :: (client: s32, store_dir: string) {
serve_one :: (client: i32, store_dir: string) {
buf : [8192]u8 = ---;
n := sock.read(client, @buf[0], 8192);
if n <= 0 { return; }
@@ -383,7 +383,7 @@ serve_one :: (client: s32, store_dir: string) {
// time — the deployment story is LAN/NAS-scale). Returns only when the
// socket can't be opened. Per-request allocations live in an arena that
// dies with the request.
run_server :: (store_dir: string, port: s64) -> !ServeErr {
run_server :: (store_dir: string, port: i64) -> !ServeErr {
fd, fe := http.listen_on(port);
if fe { raise error.Bind; }

View File

@@ -35,10 +35,10 @@ Request :: struct {
// Open a listening socket on 0.0.0.0:<port>. SO_REUSEADDR so a restarted
// server can re-bind without waiting out TIME_WAIT.
listen_on :: (port: s64) -> (s32, !HttpError) {
listen_on :: (port: i64) -> (i32, !HttpError) {
fd := sock.socket(sock.AF_INET, sock.SOCK_STREAM, 0);
if fd < 0 { raise error.Socket; }
opt : s32 = 1;
opt : i32 = 1;
sock.setsockopt(fd, sock.SOL_SOCKET, sock.SO_REUSEADDR, @opt, 4);
addr : sock.SockAddr = .{ sin_len = 16, sin_family = 2, sin_port = sock.htons(port) };
if sock.bind(fd, @addr, 16) < 0 { sock.close(fd); raise error.Bind; }
@@ -46,20 +46,20 @@ listen_on :: (port: s64) -> (s32, !HttpError) {
return fd;
}
SO_RCVTIMEO :s32: 0x1006; // macOS
SO_RCVTIMEO :i32: 0x1006; // macOS
// macOS struct timeval (padded to 16 for the setsockopt copy).
Timeval :: struct {
tv_sec: s64;
tv_usec: s32 = 0;
pad: s32 = 0;
tv_sec: i64;
tv_usec: i32 = 0;
pad: i32 = 0;
}
// Bound blocking reads on `fd` to `secs` seconds. A sequential accept
// loop needs this: browsers open speculative preconnections that never
// send bytes, and an unbounded read on one of those wedges the whole
// server while real requests sit in the backlog.
set_read_timeout :: (fd: s32, secs: s64) {
set_read_timeout :: (fd: i32, secs: i64) {
tv : Timeval = .{ tv_sec = secs };
sock.setsockopt(fd, sock.SOL_SOCKET, SO_RCVTIMEO, xx @tv, 16);
}
@@ -81,7 +81,7 @@ parse_request :: (raw: string, req: *Request) -> bool {
return true;
}
status_text :: (code: s64) -> string {
status_text :: (code: i64) -> string {
if code == 200 { return "OK"; }
if code == 400 { return "Bad Request"; }
if code == 404 { return "Not Found"; }
@@ -93,7 +93,7 @@ status_text :: (code: s64) -> string {
// Write one complete response and leave the connection for the caller to
// close. `extra` is zero or more pre-formatted header lines, each ending
// in `\r\n` ("" for none).
respond :: (client: s32, code: s64, content_type: string, extra: string, body: string) {
respond :: (client: i32, code: i64, content_type: string, extra: string, body: string) {
h := concat("HTTP/1.1 ", concat(int_to_string(code), concat(" ", status_text(code))));
h = concat(h, "\r\n");
h = concat(h, concat("Content-Type: ", concat(content_type, "\r\n")));

View File

@@ -65,7 +65,7 @@ Store :: struct {
root: string;
// Monotonic per-store counter naming `put_file`'s provisional staging
// files, so concurrent file puts don't clobber each other's temp copy.
seq: s64;
seq: i64;
init :: (root: string) -> Store {
return Store.{ root = root, seq = 0 };

View File

@@ -120,7 +120,7 @@ ext_matches_platform :: (path: string, p: Platform) -> bool {
// the first failing check (see the check order at the top of the file).
validate_artifact_file :: (
path: string,
expected_size: s64,
expected_size: i64,
expected_sha256: string,
platform: Platform,
content_type: string,

View File

@@ -45,7 +45,7 @@ contains :: (hay: string, needle: string) -> bool {
return false;
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
// ── 1. No command → readable usage on stderr, EX_USAGE (64) ───────

View File

@@ -178,14 +178,14 @@ check_artifact_metadata :: () -> bool {
return a.metadata == "{\"min_os\":\"14\"}";
}
run_case :: (label: string, ok: bool) -> s32 {
run_case :: (label: string, ok: bool) -> i32 {
if ok { print(" PASS {}\n", label); return 0; }
print(" FAIL {}\n", label);
return 1;
}
main :: () -> s32 {
failures : s32 = 0;
main :: () -> i32 {
failures : i32 = 0;
failures += run_case("accept: valid app", check_accepts_app());
failures += run_case("accept: valid release", check_accepts_release());
failures += run_case("accept: valid artifact", check_accepts_artifact());

View File

@@ -64,18 +64,18 @@ check_missing_artifact_path :: (alloc: Allocator) -> bool {
return raised and matched;
}
run_case :: (label: string, ok: bool) -> s32 {
run_case :: (label: string, ok: bool) -> i32 {
if ok { print(" PASS {}\n", label); return 0; }
print(" FAIL {}\n", label);
return 1;
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 65536);
defer arena.deinit();
failures : s32 = 0;
failures : i32 = 0;
failures += run_case("parse valid dist.json -> fields", check_parse_valid(xx arena));
failures += run_case("missing version -> MissingField", check_missing_version(xx arena));
failures += run_case("unknown platform 'psvita' -> UnknownPlatform", check_unknown_platform(xx arena));

View File

@@ -80,7 +80,7 @@ assert_fails :: (label: string, mpath: string, store: string, want_code: string,
out(concat(concat(" ", label), ": exit 1 + JSON error ok\n"));
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 1 << 20);
defer arena.deinit();

View File

@@ -33,7 +33,7 @@ STORE_REL :: ".sx-tmp/publish_happy";
cwd :: () -> string {
buf : [4096]u8 = ---;
r := c_getcwd(@buf[0], 4096);
process.assert(cast(s64) r != 0, "getcwd must succeed");
process.assert(cast(i64) r != 0, "getcwd must succeed");
n := 0;
while buf[n] != 0 { n += 1; }
return substr(string.{ ptr = @buf[0], len = n }, 0, n);
@@ -65,8 +65,8 @@ rehashes_to :: (path: string, want: string) -> bool {
}
// Count audit events whose "action" equals `action`.
count_action :: (events: Array, action: string) -> s64 {
c : s64 = 0;
count_action :: (events: Array, action: string) -> i64 {
c : i64 = 0;
i := 0;
while i < events.len {
eo := events.items[i].object;
@@ -76,7 +76,7 @@ count_action :: (events: Array, action: string) -> s64 {
return c;
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 1 << 20);
defer arena.deinit();

View File

@@ -53,8 +53,8 @@ get_obj :: (o: Object, key: string) -> Object { return get(o, key).object; }
get_arr :: (o: Object, key: string) -> Array { return get(o, key).array; }
// Count audit events whose "action" equals `action`.
count_action :: (events: Array, action: string) -> s64 {
c : s64 = 0;
count_action :: (events: Array, action: string) -> i64 {
c : i64 = 0;
i := 0;
while i < events.len {
eo := events.items[i].object;
@@ -98,7 +98,7 @@ load_db :: (scratch: Allocator) -> Object {
return dv.object;
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 1 << 20);
defer arena.deinit();

View File

@@ -48,8 +48,8 @@ get_arr :: (o: Object, key: string) -> Array { return get(o, key).array; }
// Count audit events matching (actor, action) — distinguishes the CLI's
// channel events from the publish pipeline's "ci" ones.
count_actor_action :: (events: Array, actor: string, action: string) -> s64 {
c : s64 = 0;
count_actor_action :: (events: Array, actor: string, action: string) -> i64 {
c : i64 = 0;
i := 0;
while i < events.len {
eo := events.items[i].object;
@@ -94,7 +94,7 @@ promote_cmd :: (release_id: string) -> string {
ROLLBACK_CMD :: "build/dist release rollback --app acme-app --channel beta --local-store .sx-tmp/release_ops --json 2>/dev/null";
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 1 << 20);
defer arena.deinit();

View File

@@ -20,7 +20,7 @@ process :: #import "modules/std/process.sx";
#import "../src/domain/audit.sx";
#import "../src/repo/repo.sx";
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
// Construct the repo under the tracked allocator, then leave the scope.

View File

@@ -118,7 +118,7 @@ the_event :: () -> AuditEvent {
};
}
main :: () -> s32 {
main :: () -> i32 {
root := ".sx-tmp/repo-roundtrip";
root2 := ".sx-tmp/repo-roundtrip-2";
process.run(concat("rm -rf ", root));

View File

@@ -63,7 +63,7 @@ mk_named_channel :: (app_id: string, name: string) -> Channel {
};
}
main :: () -> s32 {
main :: () -> i32 {
root := ".sx-tmp/repo-transaction";
process.run(concat("rm -rf ", root));

View File

@@ -100,7 +100,7 @@ publish_cmd :: (mpath: string) -> string {
return concat(c, " --json 2>/dev/null >/dev/null");
}
main :: () -> s32 {
main :: () -> i32 {
gpa := GPA.init();
arena := Arena.init(xx gpa, 1 << 20);
defer arena.deinit();

View File

@@ -3,7 +3,7 @@
// The runner (tests/run.sh) treats a clean exit as `ok`.
#import "modules/std.sx";
main :: () -> s32 {
main :: () -> i32 {
print("distribution smoke test: toolchain ok\n");
return 0;
}

View File

@@ -59,7 +59,7 @@ incoming_count :: (dir: string) -> string {
return res.stdout;
}
main :: () -> s32 {
main :: () -> i32 {
root := ".sx-tmp/store-cas";
process.run(concat("rm -rf ", root)); // fresh root, even after a crashed prior run

View File

@@ -83,14 +83,14 @@ check_missing_file :: () -> bool {
return failed_with(o, .missing_file);
}
run_case :: (label: string, ok: bool) -> s32 {
run_case :: (label: string, ok: bool) -> i32 {
if ok { print(" PASS {}\n", label); return 0; }
print(" FAIL {}\n", label);
return 1;
}
main :: () -> s32 {
failures : s32 = 0;
main :: () -> i32 {
failures : i32 = 0;
failures += run_case("good .apk/android_apk -> valid/ok", check_good_apk());
failures += run_case("good .ipa/ios -> valid/ok", check_good_ipa());
failures += run_case("wrong size -> size_mismatch", check_size_mismatch());