> const char *e_str(int i) > { > X(0,"no error"); > X(EINTR,"interrupted system call") > X(ENOMEM,"out of memory") > X(ENOENT,"file does not exist") > X(ETXTBSY,"text busy") > X(EIO,"input/output error") > ... > return "unknown error"; > } > > Maybe this is just comedy?
The real comedy is strerror() not being thread-safe because on certain implementation it returns a static buffer: https://man.freebsd.org/cgi/man.cgi?query=strerror&sektion=0#end > void byte_copy(void *yv, long long ylen, const void *xv) { > > long long i; > const char *x = xv; > char *y = yv; > > for (i = 0; i < ylen; ++i) y[i] = x[i]; > } > > Of course, byte_copy is superior to memcpy & strncpy here because he's > copying some pretty long(!) strings. I do no know what the purpose of this was, but interface wise, it is indeed superior to memcpy because it can deal with `n == 0 && (src == NULL || dst == NULL)` case without invoking UB: https://port70.net/~nsz/c/c99/n1256.html#7.21.1p2 | n can have the value zero [but] pointer arguments on such a call shall | still have valid values And in practice, compilers like to mark any arguments to string.h functions as non-null unconditionally due to the above reason. https://godbolt.org/z/brz7jhchr --- FYI I'm not exactly interested in defending dq because I know nothing about it, but the above criticism at least seems more like knee jerk reaction due to something being different rather than actual/technical criticism. - NRK