http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=488759...
It must have been done for a reason right, emacs is incredibly old in tech years and solid as a rock.
http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=488759...
It must have been done for a reason right, emacs is incredibly old in tech years and solid as a rock.
For example, those naming practices were pretty essential when working with 80-character monitors.
And all those ifdefs were required for dealing with DEC minicomputers and (later) microcomputers. A minicomputer, if you didn't know, was something that in terms of power and cost existed between a mainframe and microcomputer (i.e., a PC).
Breaking out the code into different functions by platform (segmented by ifdef statements) would create unnecessary code bloat unless the implementations differed significantly. And believe it or not, this was much more readable (with the technology of the time) than calling separate functions within a master function, requiring referring to each function separately. Of course, ifdefs for different platforms are still required, and are often used in a similar way today.
I guess what I'm trying to say here is that there were very practical and pragmatic reasons code used to look like this, and that things much more obscure and (to modern eyes) hard to read were written by very smart people who knew exactly what they were doing.
Saying it is indefensible to manipulate strings in C is coming pretty close to saying it is indefensible to use C (and after they went to all that work to put together C11!). For most programmers, perhaps. But it still has its uses, and as of C11 safer standard string manipulation functions, as well. A competent, security-minded C programmer can write perfectly safe string handling code in modern C.
Still, it wouldn't be my first choice. A Jedi may use a lightsaber effectively, but a novice will probably just end up cutting off his leg.
I say that - may be I led a charmed life. Sigh.
When I come across code I don't understand I base my assumptions on the belief that the original programmer was smart, knew what they were doing, and had specific reasons writing the code as such.
Quite a lot of the #ifdef damage is to deal with VMS.
Here is the same code in JOE (which has no VMS support and which treats foo/../bar and bar as different files - the original emacs code was written before symlinks!). JOE has a variable length string library, so you see 'vsncpy' instead of the alloca / strcpy / strcat / make_string.
http://sourceforge.net/p/joe-editor/mercurial/ci/default/tre...
Edit: Holy Cow! The new version in emacs is much more involved: https://github.com/emacs-mirror/emacs/blob/master/src/fileio...
"For technical reasons, this function can return correct but non-intuitive results for the root directory; for instance, (expand-file-name ".." "/") returns "/.."... " :-)
expand-file-name doesn't do that; (expand-file-name "/foo//bar") produces "/foo/bar", just like any other pathname canonicalization.
I can't help but wonder why emacs doesn't write that function in lisp, rather than C.
Maybe the code predates the lisp interpreter.
it can still be solid as a rock and be needlessly difficult to read, written in a poor style. they aren't mutually exclusive things, despite what many may preach.
Funny: Tried to find the comment commenting it out. I found it. #IF 0. Wow.
#if 0 is also a convenient way to flip bits of test/debug code on and off.
#if 0 <...> #else <...> #endif
Is a pretty standard way to switch between new/old code while refactoring to check if behavior/output matches. Just change 0 to 1 to switch between "versions".