Archive for category Gotchas

Why, resolve_path(), why?

As I alluded to in other posts, resolve_path() doesn’t behave right. In what ways does it behave wrongly? I’ll list a few.

  1. It can’t handle the empty string as parameter.
  2. It can’t handle the input ~.
  3. The expression newer[<0..<1] = curr + "/"; didn’t seem to work for me, though I get the intent.
  4. The code style is atrocious. Who the heck indented this mess?

Here’s a better version:

string resolve_path(string curr, string newer) {
    int i, j, size;
    string *tmp;
    
    switch(newer) {
    case 0:  
    case "": 
    case ".":
        return curr;

    case "~":
        return user_path((string)this_player()->query_name());
    
#ifndef __NO_ENVIRONMENT__
    case "here":
        return file_name(environment())+".c";
#endif
    
    default:
        if (newer[0..1] == "~/")
            newer = user_path((string)this_player()->query_name())
                  + newer[2..];
        else {
            switch(newer[0]) {
            case '~':
            {   
                i = strsrch(newer, '/');
                if (i < 0)
                    newer = user_path(newer[1..]);
                else
                    newer = user_path(newer[1..i-1]) + newer[i..];
                break;
            }   
            case '/':
                break;
            default:
                newer = curr + "/" + newer;
            }   
        }   
    
        if (newer[<1] != '/')
            newer += "/";
        size = sizeof(tmp = regexp(explode(newer, "/"), "."));
    
        i = j = 0;
    
        while (i < size) {
            switch(tmp[i]) {
            case "..":
                if (j) {
                    while (j-- && !tmp[j]);
                    if (j >= 0)
                        tmp[j] = 0;
                    else
                        j++;
                }
            case ".":
                tmp[i++] = 0;
                break;
            default:
                j = ++i;
                break;
            }
        }
        return "/"+implode(tmp, "/");
    }
}

Leave a comment

Variable declarations go first

Here’s a big LPC gotcha for those more familiar with…any modern programming language at all.  You can’t declare variables as you come to the points where you need them.  You must do all variable declarations as the first lines in the function body.

WRONG:


void foo ()
{
    int x = 25;
    x = x + 100;
    int y = x - 3;
    y++;
    string z = "this is all going to go so badly";
}

RIGHT:


void foo ()
{
    int x = 25;
    int y;
    string z = "this is actually going to go just fine";
    x = x + 100;
    y = x - 3;
}

Leave a comment

Learn to use kill -9

As you edit your lib’s core code, you will make mistakes that cause your lib to simply not launch.  For example, if you mess up the clone/login.c object, say, when working on the stuff in this post, you won’t be able to get into your MUD at all to issue the shutdown command.

Or you might have errors that let you log in, but that bombed half way through the initialization of your user object, so none of the commands like “quit” or “shutdown” work.  Put this together with the fact that Ctrl+Z, Ctrl+C, etc. don’t do anything, and you’re stuck in the MUD forever. :)

Fix the problem this way:

  1. Use the Unix command ps -ax to list all your processes.
  2. Find the one that’s running “telnet localhost 4000” and kill it.
  3. Find the one that’s running “./driver mudos.cfg” (or something like that) and kill it.

To kill such things from the Unix prompt, use the kill command, with -9 as the switch to mean “DO IT RIGHT AWAY AND DON’T ASK QUESTIONS!”  You pass the process ID (at the far left of the ps -ax output) as the argument(s).

Example:

$ ps -ax
...lots of output snipped...
94918 ttys000 0:00.01 ./driver ./mudos.cfg
94922 ttys000 0:00.02 telnet localhost 4000
...lots more output snipped...
$ kill -9 94922 94918

Leave a comment