@zigc/lib 0.17.0-dev.248 → 0.17.0-dev.263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1397,7 +1397,7 @@ fn makeStep(
1397
1397
  defer run.max_rss_mutex.unlock(io);
1398
1398
  run.available_rss += s.max_rss;
1399
1399
  dispatch_set.ensureUnusedCapacity(gpa, run.memory_blocked_steps.items.len) catch @panic("OOM");
1400
- while (run.memory_blocked_steps.getLastOrNull()) |candidate| {
1400
+ while (run.memory_blocked_steps.getLast()) |candidate| {
1401
1401
  if (run.available_rss < candidate.max_rss) break;
1402
1402
  assert(run.memory_blocked_steps.pop() == candidate);
1403
1403
  dispatch_set.appendAssumeCapacity(candidate);
@@ -361,7 +361,7 @@ fn parseCNumLit(mt: *MacroTranslator) ParseError!ZigNode {
361
361
  return error.ParseError;
362
362
  },
363
363
  });
364
- if (bytes.getLast() == '.') {
364
+ if (bytes.getLast().? == '.') {
365
365
  bytes.appendAssumeCapacity('0');
366
366
  } else if (mem.findAny(u8, bytes.items, ".eEpP") == null) {
367
367
  bytes.appendSliceAssumeCapacity(".0");
@@ -209,7 +209,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void {
209
209
  } else p.pending_blocks.items.len;
210
210
 
211
211
  const in_code_block = p.pending_blocks.items.len > 0 and
212
- p.pending_blocks.getLast().tag == .code_block;
212
+ p.pending_blocks.getLast().?.tag == .code_block;
213
213
  const code_block_end = in_code_block and
214
214
  first_unmatched + 1 == p.pending_blocks.items.len;
215
215
  // New blocks cannot be started if we are actively inside a code block or
@@ -225,7 +225,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void {
225
225
  if (maybe_block_start == null and
226
226
  !isBlank(rest_line) and
227
227
  p.pending_blocks.items.len > 0 and
228
- p.pending_blocks.getLast().tag == .paragraph)
228
+ p.pending_blocks.getLast().?.tag == .paragraph)
229
229
  {
230
230
  try p.addScratchStringLine(mem.trimStart(u8, rest_line, " \t"));
231
231
  return;
@@ -236,7 +236,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void {
236
236
  // paragraphs.
237
237
  if (maybe_block_start != null and
238
238
  p.pending_blocks.items.len > 0 and
239
- p.pending_blocks.getLast().tag == .paragraph)
239
+ p.pending_blocks.getLast().?.tag == .paragraph)
240
240
  {
241
241
  try p.closeLastBlock();
242
242
  }
@@ -259,7 +259,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void {
259
259
  // Do not append the end of a code block (```) as textual content.
260
260
  if (code_block_end) return;
261
261
 
262
- const can_accept = if (p.pending_blocks.getLastOrNull()) |last_pending_block|
262
+ const can_accept = if (p.pending_blocks.getLast()) |last_pending_block|
263
263
  last_pending_block.canAccept()
264
264
  else
265
265
  .blocks;
@@ -273,7 +273,7 @@ pub fn feedLine(p: *Parser, line: []const u8) Allocator.Error!void {
273
273
  // loose, since we might just be looking at a blank line after the
274
274
  // end of the last item in the list. The final determination will be
275
275
  // made when appending the next child of the list or list item.
276
- const maybe_containing_list_index = if (p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().tag == .list_item)
276
+ const maybe_containing_list_index = if (p.pending_blocks.items.len > 0 and p.pending_blocks.getLast().?.tag == .list_item)
277
277
  p.pending_blocks.items.len - 2
278
278
  else
279
279
  null;
@@ -368,7 +368,7 @@ const BlockStart = struct {
368
368
  };
369
369
 
370
370
  fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
371
- if (p.pending_blocks.getLastOrNull()) |last_pending_block| {
371
+ if (p.pending_blocks.getLast()) |last_pending_block| {
372
372
  // Close the last block if it is a list and the new block is not a list item
373
373
  // or not of the same marker type.
374
374
  const should_close_list = last_pending_block.tag == .list and
@@ -383,7 +383,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
383
383
  }
384
384
  }
385
385
 
386
- if (p.pending_blocks.getLastOrNull()) |last_pending_block| {
386
+ if (p.pending_blocks.getLast()) |last_pending_block| {
387
387
  // If the last block is a list or list item, check for tightness based
388
388
  // on the last line.
389
389
  const maybe_containing_list = switch (last_pending_block.tag) {
@@ -401,7 +401,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
401
401
  // Start a new list if the new block is a list item and there is no
402
402
  // containing list yet.
403
403
  if (block_start.tag == .list_item and
404
- (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().tag != .list))
404
+ (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().?.tag != .list))
405
405
  {
406
406
  try p.pending_blocks.append(p.allocator, .{
407
407
  .tag = .list,
@@ -417,7 +417,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
417
417
 
418
418
  if (block_start.tag == .table_row) {
419
419
  // Likewise, table rows start a table implicitly.
420
- if (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().tag != .table) {
420
+ if (p.pending_blocks.items.len == 0 or p.pending_blocks.getLast().?.tag != .table) {
421
421
  try p.pending_blocks.append(p.allocator, .{
422
422
  .tag = .table,
423
423
  .data = .{ .table = .{
@@ -429,7 +429,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
429
429
  });
430
430
  }
431
431
 
432
- const current_row = p.scratch_extra.items.len - p.pending_blocks.getLast().extra_start;
432
+ const current_row = p.scratch_extra.items.len - p.pending_blocks.getLast().?.extra_start;
433
433
  if (current_row <= 1) {
434
434
  var buffer: [max_table_columns]Node.TableCellAlignment = undefined;
435
435
  const table_row = &block_start.data.table_row;
@@ -441,7 +441,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
441
441
  // We need to go back and mark the header row and its column
442
442
  // alignments.
443
443
  const datas = p.nodes.items(.data);
444
- const header_data = datas[p.scratch_extra.getLast()];
444
+ const header_data = datas[p.scratch_extra.getLast().?];
445
445
  for (p.extraChildren(header_data.container.children), 0..) |header_cell, i| {
446
446
  const alignment = if (i < alignments.len) alignments[i] else .unset;
447
447
  const cell_data = &datas[@intFromEnum(header_cell)].table_cell;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.17.0-dev.248",
3
+ "version": "0.17.0-dev.263",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -59,7 +59,7 @@ pub fn joinStringZ(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Erro
59
59
  return p.root_dir.joinZ(gpa, parts);
60
60
  }
61
61
 
62
- pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.File.OpenFlags) !Io.File {
62
+ pub fn openFile(p: Path, io: Io, sub_path: []const u8, flags: Io.Dir.OpenFileOptions) !Io.File {
63
63
  var buf: [fs.max_path_bytes]u8 = undefined;
64
64
  const joined_path = if (p.sub_path.len == 0) sub_path else p: {
65
65
  break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
@@ -2468,7 +2468,7 @@ fn dirCreateFile(
2468
2468
  userdata: ?*anyopaque,
2469
2469
  dir: Dir,
2470
2470
  sub_path: []const u8,
2471
- flags: File.CreateFlags,
2471
+ flags: Dir.CreateFileOptions,
2472
2472
  ) File.OpenError!File {
2473
2473
  const ev: *Evented = @ptrCast(@alignCast(userdata));
2474
2474
  _ = ev;
@@ -2601,7 +2601,7 @@ fn dirOpenFile(
2601
2601
  userdata: ?*anyopaque,
2602
2602
  dir: Dir,
2603
2603
  sub_path: []const u8,
2604
- flags: File.OpenFlags,
2604
+ flags: Dir.OpenFileOptions,
2605
2605
  ) File.OpenError!File {
2606
2606
  const ev: *Evented = @ptrCast(@alignCast(userdata));
2607
2607
 
@@ -3936,7 +3936,7 @@ fn fileMemoryMapWrite(userdata: ?*anyopaque, mm: *File.MemoryMap) File.WritePosi
3936
3936
 
3937
3937
  fn processExecutableOpen(
3938
3938
  userdata: ?*anyopaque,
3939
- flags: File.OpenFlags,
3939
+ flags: Dir.OpenFileOptions,
3940
3940
  ) process.OpenExecutableError!File {
3941
3941
  const ev: *Evented = @ptrCast(@alignCast(userdata));
3942
3942
  // _NSGetExecutablePath() returns a path that might be a symlink to
package/std/Io/File.zig CHANGED
@@ -142,21 +142,12 @@ pub fn stat(file: File, io: Io) StatError!Stat {
142
142
  return io.vtable.fileStat(io.userdata, file);
143
143
  }
144
144
 
145
- /// Deprecated, renamed to `Dir.OpenFileOptions.Mode`.
146
- pub const OpenMode = Dir.OpenFileOptions.Mode;
147
-
148
145
  pub const Lock = enum {
149
146
  none,
150
147
  shared,
151
148
  exclusive,
152
149
  };
153
150
 
154
- /// Deprecated, renamed to `Dir.OpenFileOptions`
155
- pub const OpenFlags = Dir.OpenFileOptions;
156
-
157
- /// Deprecated, renamed to `Dir.CreateFileOptions`.
158
- pub const CreateFlags = Dir.CreateFileOptions;
159
-
160
151
  pub const OpenError = error{
161
152
  PipeBusy,
162
153
  NoDevice,
package/std/Io/Kqueue.zig CHANGED
@@ -877,7 +877,7 @@ fn dirAccess(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir
877
877
  _ = options;
878
878
  @panic("TODO");
879
879
  }
880
- fn dirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
880
+ fn dirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: Dir.CreateFileOptions) File.OpenError!File {
881
881
  const k: *Kqueue = @ptrCast(@alignCast(userdata));
882
882
  _ = k;
883
883
  _ = dir;
@@ -885,7 +885,7 @@ fn dirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: F
885
885
  _ = flags;
886
886
  @panic("TODO");
887
887
  }
888
- fn dirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
888
+ fn dirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: Dir.OpenFileOptions) File.OpenError!File {
889
889
  const k: *Kqueue = @ptrCast(@alignCast(userdata));
890
890
  _ = k;
891
891
  _ = dir;
package/std/Io/Uring.zig CHANGED
@@ -2812,7 +2812,7 @@ fn dirCreateFile(
2812
2812
  userdata: ?*anyopaque,
2813
2813
  dir: Dir,
2814
2814
  sub_path: []const u8,
2815
- flags: File.CreateFlags,
2815
+ flags: Dir.CreateFileOptions,
2816
2816
  ) File.OpenError!File {
2817
2817
  const ev: *Evented = @ptrCast(@alignCast(userdata));
2818
2818
 
@@ -2996,7 +2996,7 @@ fn dirOpenFile(
2996
2996
  userdata: ?*anyopaque,
2997
2997
  dir: Dir,
2998
2998
  sub_path: []const u8,
2999
- flags: File.OpenFlags,
2999
+ flags: Dir.OpenFileOptions,
3000
3000
  ) File.OpenError!File {
3001
3001
  const ev: *Evented = @ptrCast(@alignCast(userdata));
3002
3002
 
@@ -4104,7 +4104,7 @@ fn fileMemoryMapWrite(userdata: ?*anyopaque, mm: *File.MemoryMap) File.WritePosi
4104
4104
 
4105
4105
  fn processExecutableOpen(
4106
4106
  userdata: ?*anyopaque,
4107
- flags: File.OpenFlags,
4107
+ flags: Dir.OpenFileOptions,
4108
4108
  ) process.OpenExecutableError!File {
4109
4109
  const ev: *Evented = @ptrCast(@alignCast(userdata));
4110
4110
  return dirOpenFile(ev, .{ .handle = linux.AT.FDCWD }, "/proc/self/exe", flags);
package/std/Io.zig CHANGED
@@ -2922,7 +2922,7 @@ pub fn failingDirAccess(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
2922
2922
  return error.FileNotFound;
2923
2923
  }
2924
2924
 
2925
- pub fn failingDirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: File.CreateFlags) File.OpenError!File {
2925
+ pub fn failingDirCreateFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, options: Dir.CreateFileOptions) File.OpenError!File {
2926
2926
  _ = userdata;
2927
2927
  _ = dir;
2928
2928
  _ = sub_path;
@@ -2938,7 +2938,7 @@ pub fn failingDirCreateFileAtomic(userdata: ?*anyopaque, dir: Dir, sub_path: []c
2938
2938
  return error.NoSpaceLeft;
2939
2939
  }
2940
2940
 
2941
- pub fn failingDirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
2941
+ pub fn failingDirOpenFile(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, flags: Dir.OpenFileOptions) File.OpenError!File {
2942
2942
  _ = userdata;
2943
2943
  _ = dir;
2944
2944
  _ = sub_path;
@@ -3275,7 +3275,7 @@ pub fn unreachableFileMemoryMapWrite(userdata: ?*anyopaque, mm: *File.MemoryMap)
3275
3275
  unreachable;
3276
3276
  }
3277
3277
 
3278
- pub fn failingProcessExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) std.process.OpenExecutableError!File {
3278
+ pub fn failingProcessExecutableOpen(userdata: ?*anyopaque, flags: Dir.OpenFileOptions) std.process.OpenExecutableError!File {
3279
3279
  _ = userdata;
3280
3280
  _ = flags;
3281
3281
  return error.FileNotFound;
@@ -887,17 +887,25 @@ pub fn Custom(
887
887
  }
888
888
 
889
889
  /// Modify an entry's key without reordering any entries.
890
- pub fn setKey(self: *Self, gpa: Allocator, index: usize, new_key: K) Oom!void {
890
+ pub fn setKey(self: *Self, index: usize, new_key: K) void {
891
891
  if (@sizeOf(ByIndexContext) != 0)
892
892
  @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call setKeyContext instead.");
893
- return setKeyContext(self, gpa, index, new_key, undefined);
893
+ return setKeyContext(self, index, new_key, undefined);
894
894
  }
895
895
 
896
- pub fn setKeyContext(self: *Self, gpa: Allocator, index: usize, new_key: K, ctx: Context) Oom!void {
897
- const key_ptr = &self.entries.items(.key)[index];
898
- key_ptr.* = new_key;
899
- if (store_hash) self.entries.items(.hash)[index] = checkedHash(ctx, key_ptr.*);
900
- try rebuildIndex(self, gpa, undefined);
896
+ pub fn setKeyContext(self: *Self, index: usize, new_key: K, ctx: Context) void {
897
+ if (self.index_header) |header| {
898
+ self.removeFromIndexByIndex(index, if (store_hash) {} else ctx, header);
899
+
900
+ self.entries.items(.key)[index] = new_key;
901
+ const h = checkedHash(ctx, new_key);
902
+ if (store_hash) self.entries.items(.hash)[index] = h;
903
+
904
+ insertEntryIntoNewHeader(header, h, index);
905
+ } else {
906
+ self.entries.items(.key)[index] = new_key;
907
+ if (store_hash) self.entries.items(.hash)[index] = checkedHash(ctx, new_key);
908
+ }
901
909
  }
902
910
 
903
911
  fn rebuildIndex(self: *Self, gpa: Allocator, ctx: Context) Oom!void {
@@ -1420,39 +1428,50 @@ pub fn Custom(
1420
1428
  fn insertAllEntriesIntoNewHeaderGeneric(self: *Self, ctx: ByIndexContext, header: *IndexHeader, comptime I: type) void {
1421
1429
  const slice = self.entries.slice();
1422
1430
  const items = if (store_hash) slice.items(.hash) else slice.items(.key);
1423
- const indexes = header.indexes(I);
1424
1431
 
1425
- entry_loop: for (items, 0..) |key, i| {
1426
- const h = if (store_hash) key else checkedHash(ctx, key);
1427
- const start_index = safeTruncate(usize, h);
1428
- const end_index = start_index +% indexes.len;
1429
- var index = start_index;
1430
- var entry_index = @as(I, @intCast(i));
1431
- var distance_from_start_index: I = 0;
1432
- while (index != end_index) : ({
1433
- index +%= 1;
1434
- distance_from_start_index += 1;
1435
- }) {
1436
- const slot = header.constrainIndex(index);
1437
- const next_index = indexes[slot];
1438
- if (next_index.isEmpty()) {
1439
- indexes[slot] = .{
1440
- .distance_from_start_index = distance_from_start_index,
1441
- .entry_index = entry_index,
1442
- };
1443
- continue :entry_loop;
1444
- }
1445
- if (next_index.distance_from_start_index < distance_from_start_index) {
1446
- indexes[slot] = .{
1447
- .distance_from_start_index = distance_from_start_index,
1448
- .entry_index = entry_index,
1449
- };
1450
- distance_from_start_index = next_index.distance_from_start_index;
1451
- entry_index = next_index.entry_index;
1452
- }
1432
+ for (items, 0..) |hash_or_key, i| {
1433
+ const h = if (store_hash) hash_or_key else checkedHash(ctx, hash_or_key);
1434
+ insertEntryIntoNewHeaderGeneric(header, h, i, I);
1435
+ }
1436
+ }
1437
+
1438
+ fn insertEntryIntoNewHeader(header: *IndexHeader, h: u32, i: usize) void {
1439
+ switch (header.capacityIndexType()) {
1440
+ .u8 => insertEntryIntoNewHeaderGeneric(header, h, i, u8),
1441
+ .u16 => insertEntryIntoNewHeaderGeneric(header, h, i, u16),
1442
+ .u32 => insertEntryIntoNewHeaderGeneric(header, h, i, u32),
1443
+ }
1444
+ }
1445
+ fn insertEntryIntoNewHeaderGeneric(header: *IndexHeader, h: u32, i: usize, comptime I: type) void {
1446
+ const indexes = header.indexes(I);
1447
+ const start_index = safeTruncate(usize, h);
1448
+ const end_index = start_index +% indexes.len;
1449
+ var index = start_index;
1450
+ var entry_index: I = @intCast(i);
1451
+ var distance_from_start_index: I = 0;
1452
+ while (index != end_index) : ({
1453
+ index +%= 1;
1454
+ distance_from_start_index += 1;
1455
+ }) {
1456
+ const slot = header.constrainIndex(index);
1457
+ const next_index = indexes[slot];
1458
+ if (next_index.isEmpty()) {
1459
+ indexes[slot] = .{
1460
+ .distance_from_start_index = distance_from_start_index,
1461
+ .entry_index = entry_index,
1462
+ };
1463
+ return;
1464
+ }
1465
+ if (next_index.distance_from_start_index < distance_from_start_index) {
1466
+ indexes[slot] = .{
1467
+ .distance_from_start_index = distance_from_start_index,
1468
+ .entry_index = entry_index,
1469
+ };
1470
+ distance_from_start_index = next_index.distance_from_start_index;
1471
+ entry_index = next_index.entry_index;
1453
1472
  }
1454
- unreachable;
1455
1473
  }
1474
+ unreachable;
1456
1475
  }
1457
1476
 
1458
1477
  fn checkedHash(ctx: anytype, key: anytype) u32 {
@@ -2118,7 +2137,7 @@ test "setKey storehash true" {
2118
2137
  try map.put(gpa, 12, 34);
2119
2138
  try map.put(gpa, 56, 78);
2120
2139
 
2121
- try map.setKey(gpa, 0, 42);
2140
+ map.setKey(0, 42);
2122
2141
  try testing.expectEqual(2, map.count());
2123
2142
  try testing.expectEqual(false, map.contains(12));
2124
2143
  try testing.expectEqual(34, map.get(42));
@@ -2134,13 +2153,49 @@ test "setKey storehash false" {
2134
2153
  try map.put(gpa, 12, 34);
2135
2154
  try map.put(gpa, 56, 78);
2136
2155
 
2137
- try map.setKey(gpa, 0, 42);
2156
+ map.setKey(0, 42);
2138
2157
  try testing.expectEqual(2, map.count());
2139
2158
  try testing.expectEqual(false, map.contains(12));
2140
2159
  try testing.expectEqual(34, map.get(42));
2141
2160
  try testing.expectEqual(78, map.get(56));
2142
2161
  }
2143
2162
 
2163
+ test "setKey storehash false with index" {
2164
+ const gpa = std.testing.allocator;
2165
+
2166
+ const T = ArrayHashMap(usize, usize, AutoContext(usize), false);
2167
+
2168
+ var map: T = .empty;
2169
+ defer map.deinit(gpa);
2170
+
2171
+ for (0..T.linear_scan_max + 1) |i| try map.put(gpa, i, i);
2172
+
2173
+ map.setKey(0, 42);
2174
+ try testing.expectEqual(T.linear_scan_max + 1, map.count());
2175
+ try testing.expectEqual(false, map.contains(0));
2176
+ try testing.expectEqual(0, map.get(42));
2177
+
2178
+ for (1..T.linear_scan_max + 1) |i| try testing.expectEqual(i, map.get(i));
2179
+ }
2180
+
2181
+ test "setKey storehash true with index" {
2182
+ const gpa = std.testing.allocator;
2183
+
2184
+ const T = ArrayHashMap(usize, usize, AutoContext(usize), false);
2185
+
2186
+ var map: ArrayHashMap(usize, usize, AutoContext(usize), true) = .empty;
2187
+ defer map.deinit(gpa);
2188
+
2189
+ for (0..T.linear_scan_max + 1) |i| try map.put(gpa, i, i);
2190
+
2191
+ map.setKey(0, 42);
2192
+ try testing.expectEqual(T.linear_scan_max + 1, map.count());
2193
+ try testing.expectEqual(false, map.contains(0));
2194
+ try testing.expectEqual(0, map.get(42));
2195
+
2196
+ for (1..T.linear_scan_max + 1) |i| try testing.expectEqual(i, map.get(i));
2197
+ }
2198
+
2144
2199
  pub fn getHashPtrAddrFn(comptime K: type, comptime Context: type) (fn (Context, K) u32) {
2145
2200
  return struct {
2146
2201
  fn hash(ctx: Context, key: K) u32 {
@@ -544,16 +544,13 @@ pub fn AlignedManaged(comptime T: type, comptime alignment: ?mem.Alignment) type
544
544
  return self.allocatedSlice()[self.items.len..];
545
545
  }
546
546
 
547
- /// Returns the last element from the list.
548
- /// Asserts that the list is not empty.
549
- pub fn getLast(self: Self) T {
550
- return self.items[self.items.len - 1];
551
- }
547
+ /// Deprecated in favor of `getLast`
548
+ pub const getLastOrNull = getLast;
552
549
 
553
- /// Returns the last element from the list, or `null` if list is empty.
554
- pub fn getLastOrNull(self: Self) ?T {
550
+ /// Returns the last element from the list, or `null` if the list is empty.
551
+ pub fn getLast(self: Self) ?T {
555
552
  if (self.items.len == 0) return null;
556
- return self.getLast();
553
+ return self.items[self.items.len - 1];
557
554
  }
558
555
  };
559
556
  }
@@ -1394,17 +1391,10 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
1394
1391
  return self.allocatedSlice()[self.items.len..];
1395
1392
  }
1396
1393
 
1397
- /// Return the last element from the list.
1398
- /// Asserts that the list is not empty.
1399
- pub fn getLast(self: Self) T {
1400
- return self.items[self.items.len - 1];
1401
- }
1402
-
1403
- /// Return the last element from the list, or
1404
- /// return `null` if list is empty.
1405
- pub fn getLastOrNull(self: Self) ?T {
1394
+ /// Returns the last element from the list, or `null` if the list is empty.
1395
+ pub fn getLast(self: Self) ?T {
1406
1396
  if (self.items.len == 0) return null;
1407
- return self.getLast();
1397
+ return self.items[self.items.len - 1];
1408
1398
  }
1409
1399
 
1410
1400
  /// Called when memory growth is necessary. Returns a capacity larger than
@@ -2394,22 +2384,11 @@ test "Managed(u32).getLast()" {
2394
2384
  var list = Managed(u32).init(a);
2395
2385
  defer list.deinit();
2396
2386
 
2397
- try list.append(2);
2398
- const const_list = list;
2399
- try testing.expectEqual(const_list.getLast(), 2);
2400
- }
2401
-
2402
- test "Managed(u32).getLastOrNull()" {
2403
- const a = testing.allocator;
2404
-
2405
- var list = Managed(u32).init(a);
2406
- defer list.deinit();
2407
-
2408
- try testing.expectEqual(list.getLastOrNull(), null);
2387
+ try testing.expectEqual(list.getLast(), null);
2409
2388
 
2410
2389
  try list.append(2);
2411
2390
  const const_list = list;
2412
- try testing.expectEqual(const_list.getLastOrNull().?, 2);
2391
+ try testing.expectEqual(const_list.getLast().?, 2);
2413
2392
  }
2414
2393
 
2415
2394
  test "return OutOfMemory when capacity would exceed maximum usize integer value" {
package/std/c.zig CHANGED
@@ -11619,6 +11619,7 @@ const private = struct {
11619
11619
  extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path: [*:0]const u8, buf: *Stat, flag: u32) c_int;
11620
11620
  extern "c" fn @"readdir$INODE64"(dir: *DIR) ?*dirent;
11621
11621
  extern "c" fn @"stat$INODE64"(noalias path: [*:0]const u8, noalias buf: *Stat) c_int;
11622
+ extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *Stat) c_int;
11622
11623
 
11623
11624
  /// macos modernized symbols.
11624
11625
  extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
package/std/deque.zig CHANGED
@@ -696,7 +696,7 @@ fn fuzzAgainstArrayList(_: void, smith: *std.testing.Smith) anyerror!void {
696
696
  try q.ensureTotalCapacityPrecise(q_gpa, q.len + growth);
697
697
  },
698
698
  }
699
- try testing.expectEqual(l.getLastOrNull(), q.back());
699
+ try testing.expectEqual(l.getLast(), q.back());
700
700
  try testing.expectEqual(
701
701
  if (l.items.len > 0) l.items[0] else null,
702
702
  q.front(),
package/std/process.zig CHANGED
@@ -3,6 +3,7 @@ const native_os = builtin.os.tag;
3
3
 
4
4
  const std = @import("std.zig");
5
5
  const Io = std.Io;
6
+ const Dir = std.Io.Dir;
6
7
  const File = std.Io.File;
7
8
  const fs = std.fs;
8
9
  const mem = std.mem;
@@ -784,7 +785,7 @@ pub fn executableDirPathAlloc(io: Io, allocator: Allocator) ExecutablePathAllocE
784
785
 
785
786
  pub const OpenExecutableError = File.OpenError || ExecutablePathError || File.LockError;
786
787
 
787
- pub fn openExecutable(io: Io, flags: File.OpenFlags) OpenExecutableError!File {
788
+ pub fn openExecutable(io: Io, flags: Dir.OpenFileOptions) OpenExecutableError!File {
788
789
  return io.vtable.processExecutableOpen(io.userdata, flags);
789
790
  }
790
791
 
package/std/start.zig CHANGED
@@ -23,6 +23,10 @@ comptime {
23
23
  const dll_main_crt_startup = if (builtin.abi.isGnu()) "DllMainCRTStartup" else "_DllMainCRTStartup";
24
24
  if (native_os == .windows and !builtin.link_libc and !@hasDecl(root, dll_main_crt_startup)) {
25
25
  @export(&DllMainCRTStartup, .{ .name = dll_main_crt_startup });
26
+ } else if (native_os == .windows and builtin.link_libc and @hasDecl(root, "DllMain")) {
27
+ if (!@typeInfo(@TypeOf(root.DllMain)).@"fn".calling_convention.eql(.winapi)) {
28
+ @export(&DllMain, .{ .name = "DllMain" });
29
+ }
26
30
  }
27
31
  } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) {
28
32
  if (builtin.link_libc and @hasDecl(root, "main")) {
@@ -82,12 +86,20 @@ fn DllMainCRTStartup(
82
86
  }
83
87
 
84
88
  if (@hasDecl(root, "DllMain")) {
85
- return root.DllMain(hinstDLL, fdwReason, lpReserved);
89
+ return root.DllMain(@ptrCast(hinstDLL), fdwReason, lpReserved);
86
90
  }
87
91
 
88
92
  return .TRUE;
89
93
  }
90
94
 
95
+ fn DllMain(
96
+ hinstDLL: std.os.windows.HINSTANCE,
97
+ fdwReason: std.os.windows.DWORD,
98
+ lpReserved: std.os.windows.LPVOID,
99
+ ) callconv(.winapi) std.os.windows.BOOL {
100
+ return root.DllMain(@ptrCast(hinstDLL), fdwReason, lpReserved);
101
+ }
102
+
91
103
  fn wasm_freestanding_start() callconv(.c) void {
92
104
  // This is marked inline because for some reason LLVM in
93
105
  // release mode fails to inline it, and we want fewer call frames in stack traces.
package/std/std.zig CHANGED
@@ -65,7 +65,8 @@ pub const array_hash_map = @import("array_hash_map.zig");
65
65
  pub const atomic = @import("atomic.zig");
66
66
  pub const base64 = @import("base64.zig");
67
67
  pub const bit_set = @import("bit_set.zig");
68
- pub const builtin = @import("builtin.zig");
68
+ pub const builtin = lang;
69
+ pub const lang = @import("builtin.zig");
69
70
  pub const c = @import("c.zig");
70
71
  pub const coff = @import("coff.zig");
71
72
  pub const compress = @import("compress.zig");
@@ -3442,7 +3442,7 @@ const AutoIndentingStream = struct {
3442
3442
  /// Sets current indentation level to be the same as that of the last pushSpace.
3443
3443
  pub fn enableSpaceMode(ais: *AutoIndentingStream, space: Space) void {
3444
3444
  if (ais.space_stack.items.len == 0) return;
3445
- const curr = ais.space_stack.getLast();
3445
+ const curr = ais.space_stack.getLast().?;
3446
3446
  if (curr.space != space) return;
3447
3447
  ais.space_mode = curr.indent_count;
3448
3448
  }
@@ -3453,7 +3453,7 @@ const AutoIndentingStream = struct {
3453
3453
 
3454
3454
  pub fn lastSpaceModeIndent(ais: *AutoIndentingStream) usize {
3455
3455
  if (ais.space_stack.items.len == 0) return 0;
3456
- return ais.space_stack.getLast().indent_count * ais.indent_delta;
3456
+ return ais.space_stack.getLast().?.indent_count * ais.indent_delta;
3457
3457
  }
3458
3458
 
3459
3459
  /// Push default indentation
@@ -5,6 +5,7 @@ const builtin = @import("builtin");
5
5
  const is_darwin = builtin.target.os.tag.isDarwin();
6
6
  const is_windows = builtin.target.os.tag == .windows;
7
7
  const is_haiku = builtin.target.os.tag == .haiku;
8
+ const is_serenity = builtin.target.os.tag == .serenity;
8
9
 
9
10
  const std = @import("std");
10
11
  const Io = std.Io;
@@ -112,7 +113,7 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const
112
113
  return error.ParseError;
113
114
  }
114
115
 
115
- if (self.gcc_dir == null and os_tag == .haiku) {
116
+ if (self.gcc_dir == null and (os_tag == .haiku or os_tag == .serenity)) {
116
117
  log.err("gcc_dir may not be empty for {s}", .{@tagName(os_tag)});
117
118
  return error.ParseError;
118
119
  }
@@ -207,8 +208,12 @@ pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!Lib
207
208
  try self.findNativeCrtDirWindows(gpa, io, args.target, sdk);
208
209
  } else if (is_haiku) {
209
210
  try self.findNativeIncludeDirPosix(gpa, io, args);
210
- try self.findNativeGccDirHaiku(gpa, io, args);
211
+ try self.findNativeGccDirPosix(gpa, io, args);
211
212
  self.crt_dir = try gpa.dupe(u8, "/system/develop/lib");
213
+ } else if (is_serenity) {
214
+ try self.findNativeIncludeDirPosix(gpa, io, args);
215
+ try self.findNativeGccDirPosix(gpa, io, args);
216
+ self.crt_dir = try gpa.dupe(u8, "/usr/lib");
212
217
  } else if (builtin.target.os.tag == .illumos) {
213
218
  // There is only one libc, and its headers/libraries are always in the same spot.
214
219
  self.include_dir = try gpa.dupe(u8, "/usr/include");
@@ -314,7 +319,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
314
319
  const include_dir_example_file = if (is_haiku) "posix/stdlib.h" else "stdlib.h";
315
320
  const sys_include_dir_example_file = if (is_windows)
316
321
  "sys\\types.h"
317
- else if (is_haiku)
322
+ else if (is_haiku or is_serenity)
318
323
  "errno.h"
319
324
  else
320
325
  "sys/errno.h";
@@ -457,7 +462,7 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args:
457
462
  });
458
463
  }
459
464
 
460
- fn findNativeGccDirHaiku(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
465
+ fn findNativeGccDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
461
466
  self.gcc_dir = try ccPrintFileName(gpa, io, .{
462
467
  .environ_map = args.environ_map,
463
468
  .search_basename = "crtbeginS.o",
@@ -949,6 +954,22 @@ pub const CrtBasenames = struct {
949
954
  },
950
955
  .static_exe, .static_pie => .{},
951
956
  },
957
+ .serenity => switch (mode) {
958
+ .dynamic_lib => .{
959
+ .crtbegin = "crtbeginS.o",
960
+ .crtend = "crtendS.o",
961
+ },
962
+ .dynamic_exe, .static_exe => .{
963
+ .crt0 = "crt0.o",
964
+ .crtbegin = "crtbegin.o",
965
+ .crtend = "crtend.o",
966
+ },
967
+ .dynamic_pie, .static_pie => .{
968
+ .crt0 = "crt0.o",
969
+ .crtbegin = "crtbeginS.o",
970
+ .crtend = "crtendS.o",
971
+ },
972
+ },
952
973
  else => .{},
953
974
  };
954
975
  }
@@ -993,7 +1014,7 @@ pub fn resolveCrtPaths(
993
1014
  .crtn = if (crt_basenames.crtn) |basename| try crt_dir_path.join(arena, basename) else null,
994
1015
  };
995
1016
  },
996
- .haiku => {
1017
+ .haiku, .serenity => {
997
1018
  const gcc_dir_path: Path = .{
998
1019
  .root_dir = std.Build.Cache.Directory.cwd(),
999
1020
  .sub_path = lci.gcc_dir orelse return error.LibCInstallationMissingCrtDir,
@@ -891,7 +891,7 @@ const MsvcLibDir = struct {
891
891
 
892
892
  lib_dir_buf.appendSliceAssumeCapacity(installation_path);
893
893
 
894
- if (!Dir.path.isSep(lib_dir_buf.getLast())) {
894
+ if (!Dir.path.isSep(lib_dir_buf.getLast().?)) {
895
895
  try lib_dir_buf.append('\\');
896
896
  }
897
897
  const installation_path_with_trailing_sep_len = lib_dir_buf.items.len;
@@ -1064,7 +1064,7 @@ const MsvcLibDir = struct {
1064
1064
  errdefer msvc_dir.deinit();
1065
1065
 
1066
1066
  // String might contain trailing slash, so trim it here
1067
- if (msvc_dir.items.len > "C:\\".len and msvc_dir.getLast() == '\\') _ = msvc_dir.pop();
1067
+ if (msvc_dir.items.len > "C:\\".len and msvc_dir.getLast().? == '\\') _ = msvc_dir.pop();
1068
1068
 
1069
1069
  // Remove `\include` at the end of path
1070
1070
  if (std.mem.endsWith(u8, msvc_dir.items, "\\include")) {
@@ -1108,7 +1108,7 @@ const MsvcLibDir = struct {
1108
1108
 
1109
1109
  try list.appendSlice(VS140COMNTOOLS); // C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools
1110
1110
  // String might contain trailing slash, so trim it here
1111
- if (list.items.len > "C:\\".len and list.getLast() == '\\') _ = list.pop();
1111
+ if (list.items.len > "C:\\".len and list.getLast().? == '\\') _ = list.pop();
1112
1112
  list.shrinkRetainingCapacity(list.items.len - "\\Common7\\Tools".len); // C:\Program Files (x86)\Microsoft Visual Studio 14.0
1113
1113
  break :base_path list;
1114
1114
  }
@@ -1131,7 +1131,7 @@ const MsvcLibDir = struct {
1131
1131
  errdefer path.deinit();
1132
1132
 
1133
1133
  // String might contain trailing slash, so trim it here
1134
- if (path.items.len > "C:\\".len and path.getLast() == '\\') _ = path.pop();
1134
+ if (path.items.len > "C:\\".len and path.getLast().? == '\\') _ = path.pop();
1135
1135
  break :base_path path;
1136
1136
  }
1137
1137
  return error.PathNotFound;
@@ -2310,7 +2310,7 @@ pub fn trailingStrtabString(self: *Builder) Allocator.Error!StrtabString {
2310
2310
  }
2311
2311
 
2312
2312
  pub fn trailingStrtabStringAssumeCapacity(self: *Builder) StrtabString {
2313
- const start = self.strtab_string_indices.getLast();
2313
+ const start = self.strtab_string_indices.getLast().?;
2314
2314
  const bytes: []const u8 = self.strtab_string_bytes.items[start..];
2315
2315
  const gop = self.strtab_string_map.getOrPutAssumeCapacityAdapted(bytes, StrtabString.Adapter{ .builder = self });
2316
2316
  if (gop.found_existing) {
@@ -8905,7 +8905,7 @@ pub fn deinit(self: *Builder) void {
8905
8905
 
8906
8906
  pub fn finishModuleAsm(self: *Builder, aw: *Writer.Allocating) Allocator.Error!void {
8907
8907
  self.module_asm = aw.toArrayList();
8908
- if (self.module_asm.getLastOrNull()) |last| if (last != '\n')
8908
+ if (self.module_asm.getLast()) |last| if (last != '\n')
8909
8909
  try self.module_asm.append(self.gpa, '\n');
8910
8910
  }
8911
8911
 
@@ -8951,7 +8951,7 @@ pub fn trailingString(self: *Builder) Allocator.Error!String {
8951
8951
  }
8952
8952
 
8953
8953
  pub fn trailingStringAssumeCapacity(self: *Builder) String {
8954
- const start = self.string_indices.getLast();
8954
+ const start = self.string_indices.getLast().?;
8955
8955
  const bytes: []const u8 = self.string_bytes.items[start..];
8956
8956
  const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
8957
8957
  if (gop.found_existing) {
@@ -12150,7 +12150,7 @@ pub fn trailingMetadataString(self: *Builder) Allocator.Error!Metadata.String {
12150
12150
  }
12151
12151
 
12152
12152
  pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String {
12153
- const start = self.metadata_string_indices.getLast();
12153
+ const start = self.metadata_string_indices.getLast().?;
12154
12154
  const bytes: []const u8 = self.metadata_string_bytes.items[start..];
12155
12155
  assert(bytes.len > 0);
12156
12156
  const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, Metadata.String.Adapter{ .builder = self });