Well, usually I find something strange and inspired by Cthulhu, every time I sit down and look at the ROM code for a bit. This time is no exception, but I figured I'd make a thread just for that kind of thing. :)

Today's "WTF" moment, comes from merc.h. You've all used our beloved MAX_STRING_LENGTH define, and I'm sure like myself, you never really bothered to look at what it was defined as. I mean, MAX_INPUT_LENGTH is 256, so some reasonable value like 1024, 2048, 4096, etc… right?

#define MAX_STRING_LENGTH 4608

W.T.F???

Where the hell does THAT number come from? I actually sat and tried to think of why they'd pick it. 4096 + 512 == 4608, but why the extra 512 overhead? Why not just make it 4096… or 8192 if that's not big enough? 4608 / 4 == 1152. Maybe they used a screen resolution of 1152 x 864???

Ok, well… eventually it won't matter, but for now I cared because the C++ format routine I have uses a pre-allocated stack buffer of a "usually works" size to avoid having to allocate memory for vsnprintf. I wanted to look up what value to put in there. :)

I find some of them to be very amusing…. The first one I looked at was in the do_sockets() command. It declares a double-sized buffer so it can loop through all the descriptors, sprintf'ing socket data into a temp buffer… and then using page_to_char to send it to the user.

Ummmm, why not just use page_to_char inside the loop? It doesn't actually get sent until their buffer gets flushed in the update loop, so it's not like it'll come up half-finished…

I get the feeling that lots of people WRITE code for diku derivatives, but very few of them READ what's already there first. :)

I find some of them to be very amusing…. The first one I looked at was in the do_sockets() command. It declares a double-sized buffer so it can loop through all the descriptors, sprintf'ing socket data into a temp buffer… and then using page_to_char to send it to the user.

Ummmm, why not just use page_to_char inside the loop? It doesn't actually get sent until their buffer gets flushed in the update loop, so it's not like it'll come up half-finished…

I get the feeling that lots of people WRITE code for diku derivatives, but very few of them READ what's already there first. :)

Eh, really, to be honest, these strings shouldn't be being allocated like this in the first place… :wink: I'm inclined to agree with ghasatta, I wouldn't spend too much time trying to figure out the deeper meaning behind these. :lol:

Non-arbitrary fixed-sized buffer lenghts, maybe? Using dynamically-allocated buffers where appropriate? Removing the use of buffers entirely where they shouldn't be used or where simpler solutions could be created?

I saw an example in another thread where a user wanted to colorize some output, so he had to create a buffer, call a function on the input string to spit the terminal control codes into the buffer. and then send that to a send_to_char function. Why not just make a send_to_char_color function that does that in one go, without a ton of extra copies and buffers?

I also see a lot of things like sprintf()ing a bunch of times into a buffer which is then passed to send_to_char. Why not a printf_to_char function? Why append to a buffer over and over and then pass that to send_to_char instead of just calling send_to_char directly several times? That would have less overhead with any sane implementation of send_to_char.

As far as picking an arbitrary size… I suppose one has to do that if you're going to use stack buffers… but why not pick a nice even power of two? Working under the assumption that computers like powers of two, and that the paging subsystem is likely going to allocate pages in powers of two, it seems to me that choosing something that will be evenly divisible by (or into) the page size is a good idea.

Since 4K seems to be roughly the number they were aiming for, 4096 seems like a good number to try.

However, I agree… the use of varargs functions was either outside the ancestral Diku coder's knowledge, or perhaps gcc didn't support such things back then (although I'm pretty sure it did).

One of the first things I do to a diku-base is make printf-style functions for all the various send_to_foo's and act. The more I work with one_argument(), the more I start wondering if a proper parser might be in order as well.

one_argument() take a string skips past leading whitespace, lobs off a chunk of it to pass back as a substring, using whitespace as a delimiter. It also attempts to handle quotes, although you can confuse it with things like [ pick up "Bob's shovel"]. It then continues to shovel past whitespace and returns the point in the string where it stops.

That's rather messy.

A proper parser would work by matching the structure of the line against known possibilities in the grammer. If you have a verb that requires 3 arguments, you just specify it that way. Since a diku is hard-coded anyways, rebuilding the grammer isn't an issue. I dunno, it's been a while since I worked with lex and yacc (flex and bison these days), so maybe it's harder than I remember.