Saturday, October 3, 2015

VerySillyMUD: Remaining compilation errors

This post is part of my "VerySillyMUD" series, chronicling an attempt to refactor an old MUD into working condition[1].

In this edition, we'll try to fix all the remaining compilation errors. The next error we have is in handler.c:

As before, we'll fix this by converting it into a comment. The code clearly isn't used, but this is an unfamiliar codebase so I don't want to throw code away (yet). Easy enough. Next error:

Now this is truly frightening. Someone is calling malloc with the wrong number of arguments; this is almost certainly the source of some kind of nefarious memory bug. What's going on here? A glance at the source code enlightens us:

The parallelism in the code here now makes this clear once we can see the associated realloc() call, which takes a pointer to the old allocation (script_data[top_of_scripts].script). This pointer is not needed for the initial malloc call, so we can remove it. Next up we have:

Ok, that's a straightforward error, but how do we fix it? Let's look at this function:

The error occurs at the first return statement. This function appears to reference special procedures; as I recall, certain areas or creatures ("mobs") in the MUD had unusual behaviors or triggers. Looking at the rest of the body of this function, it seems to be looking for special procedures and firing them, returning a 1 if one was found. Since the first return statement doesn't seem to fire any, it seems that returning 0 there is probably the correct return value. Next error:

Here the code is using a deprecated header file (malloc.h) and we can just include stdlib.h instead. Fixing that let the compilation of utility.c get further:

Ah, our good friend "#ifdef 0" again. Let's turn you into a comment instead. Next:

Hmm, we'll have to take a look at this shop_keeper function, which presumably operates the many places in the MUD where your character could buy items.

Ok, what seems to be happening here is that the function returns TRUE when the shopkeeper has performed some special behavior, and FALSE otherwise. It seems like the three return statements causing the errors are the ones up at the top of the function doing early exits from the function; it seems reasonable to guess that we should return FALSE in these cases, but we really don't have any way to tell without a much closer understanding of the codebase, which we're not going to attempt to get yet. Next error:

Another missing return value; we'll guess we should supply another zero here for this early-exit case.

More missing return values! This time, it turns out all the return statements in the DamageMessages() function don't have return values; this leads me to suspect the return type of this function is wrong. A quick grep confirms that none of the callers capture or inspect a return value, so we'll just change the return type to void. Next:

As with the shop_keeper() function we saw above, the missing return value is on an early exit from the function, which manages characters interacting with the bank and returns TRUE if such an interaction occurs. The early exit happens if IS_NPC() is true for the character. An NPC is a non-player character, i.e. one played by the program and not by a human; presumably NPCs can't interact with the bank, so it seems returning FALSE in this case would be right. Next:

We saw log_msg() in our previous post. It's defined this way:

Note the commentary left by a developer on this one-liner, which is near the top of its file and hence looked like a function prototype. At any rate, we see that log_msg() is really shorthand for calling a different logging function, log_sev(), with a priority of 1. It seems like our error in board.c was either meant to call log_sev() directly or just accidentally added an argument:

Since the other error message here just invokes log_msg() for what would seem to be an equivalently serious error, we'll change the problematic invocation to match. Next:

More missing return values. We'll default them to returning FALSE. Next:

If we supply one more FALSE then the whole thing compiles into an executable called dmserver. Let's try to run it!

Well, not so hot, but we'll leave fixing it to the next episode.

[1] SillyMUD was a derivative of DikuMUD, which was originally created by Sebastian Hammer, Michael Seifert, Hans Henrik Stærfeldt, Tom Madsen, and Katja Nyboe.