recreate for agit-test, see #32096 and also Coordinate interdependence. Demo and promote free and open source projects. Package curation. Meetups. Learning about computers.
Contributes to: #30978
libzigc: dirname #35755
chrboesch/libzigc-dirname into master
AGit
The musl version returns "." and "/" as pointers to constant memory. If you try to modify the result of dirname in that case, you get a segfault:
char const* path = "//";
char* dirc = strdup(path);
dname = dirname(NULL);
dname[0] = ':'; /* segfaults */
In your zig implementation the non const pointer returned by dirname actually points to mutable memory, but the contents of
dot_buf and slash_bufcan be silently overriden which changes the behaviour of future calls to dirname.
I'm not sure which behaviour is better, but I would tend to either matching the musl implementation or setting dot_buf = .{ '.', 0 }; and slash_buf = .{ '/', 0 }; before returing pointers to dot_buf/slash_buf
@ -0,0 +26,4 @@
while(true):(i-=1){
if(ptr[i]!='/')break;
if(i==0)returnslash;
}
why not:
while(ptr[i]=='/'):(i-=1){if(i==0)returnslash;}
readability
I'd argue using @constCast instead of pointers to mutable globals would be better here. it matches what musl does and if a caller writes through the returned pointer it just faults instead of silently corrupting buffer for later calls.
so it would look like:
constdot:[1:0]c_char=.{'.'};constslash:[1:0]c_char=.{'/'};// ...return@constCast(&dot);return@constCast(&slash);
@ -0,0 +14,4 @@
fndirname(s:?[*:0]c_char)callconv(.c)[*:0]c_char{
constdot:[*:0]c_char=@ptrCast(&dot_buf);
constslash:[*:0]c_char=@ptrCast(&slash_buf);
no need for a @ptrCast here, this works:
vardot_buf:[1:0]c_char=.{'.'};varslash_buf:[1:0]c_char=.{'/'};exportfndirname(s:?[*:0]c_char)callconv(.c)[*:0]c_char{constdot:[*:0]c_char=&dot_buf;constslash:[*:0]c_char=&slash_buf;
@ -0,0 +21,4 @@
constptr=s.?;
if(ptr[0]==0)returndot;
vari=std.mem.len(@as([*:0]u8,@ptrCast(ptr)))-1;
why the cast to [*:0]u8?
strlen is implemented like so in compiler_rt:
fnstrlen(s:[*:0]constc_char)callconv(.c)usize{returnstd.mem.len(s);}
strlen has a non-optional pointer.
strlen has a non-optional pointer. But I will do this instead:
const ptr = s orelse return @constCast(&dot);
var i = std.mem.len(ptr) - 1;
I'd argue using @constCast instead of pointers to mutable globals would be better here.
agree
9b04e03d8c
d412f3cdca
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?