General C String Library (for MUDs)
===================================
Disclaimer
==========
As awlays, I retain no responsibility if this code does anything to your code, your game, or
the system it's running on.
I understand there are many versions of some functions (particularly string comparison) I have written out there.
Use whatever you see fit. I wrote all of this specifically for the competition, and I do not claim any of them
to be the best out there.
General Information
===================
This code was written for the MudMagic Code Challenge - Mud String Library. While it isn't MUD specific,
many of the techniques used in string handling will be very handy for MUDs (especially token handling).
You can see the examples I tested this code with at http:Included in this library are 13 end-user functions (and two case-sensitive versions of two functions).
Here is a list:
--
char *duration_to_str( int secs, int format );
char *int_to_str( int num, short full );
short change_case_str( char* str, short new_case );
char *find_between( char *src, char a, char b );
char *replace_str( const char *new_str, const char *replace, const char *src );
short prefix_str(const char *str_a, const char *str_b);
short prefix_str_case(const char *str_a, const char *str_b);
short compare_str( const char* str_a, const char* str_b );
short compare_str_case( const char* str_a, const char* str_b );
int find_str( const char* find, const char* search, short sense );
char* wordwrap_str( const char* src, short num_columns, const char* nstr );
short compare_tokens( char* list_a, char* list_b, char delimiter, short prefixes );
char *grab_token( char *src, char* end_buf, char delimiter );
int total_tokens( char *src, char delimiter );
char *sentence_from_tokens( char *tokens, char delim, short word );
--
You can find general descriptions in str_lib.h. Each function has a descriptive comment specifying
the functions purpose, its returns, and any other notes in str_lib.c.
I tested the code on SWFotE 2.1a (since SWR 1.2 FUSS is missing on MudMagic). The base itself will compile
with some warnings. The default admin character is named User, and its password is "password".
(To get it running you may have to clear the blackmarket ship list and comment out data relating to extra
ports in the main function (comm.c))
Also included is an in-game command that will test all of the above functions and display the output to the character.
This should work on SMAUG and any derivitive. The library itself (that is, minus the in-game commmand) should
work in every C program.
Instructions
============
(1) mud.h
Find:
#define LEVEL_AVATAR (MAX_LEVEL - 5)
Add (under):
#include "std_lib.h"
(2) Makefile
Add str_lib.c to the C_FILES section, making it look like this:
C_FILES = 11.c act_comm.c act_info.c act_move.c act_obj.c act_wiz.c boards.c \
bounty.c build.c changes.c clans.c color.c comm.c comments.c \
const.c db.c editor.c fight.c finfo.c force.c fskills.c \
functions.c handler.c hashstr.c hunter.c id.c interp.c magic.c \
makeobjs.c marriage.c md5.c misc.c mud_comm.c mud_prog.c newarena.c \
pfiles.c planets.c player.c renumber.c reset.c save.c ships.c \
shops.c skills.c slay.c slicers.c slotm.c space.c special.c \
swskills.c tables.c tech.c track.c update.c str_lib.c
(3) Add the following code for do_teststrlib to act_info.c or another file containing commands
void do_teststrlib( CHAR_DATA *ch, char *argument )
{
char buf[MSL];
char str[] = "this is a string for testing <text between>";
char str2[] = "STRING";
char wrap[] = "This is a long string. I'm testing the wordwrap_str function in hopes that it will format this string to a reasonable length. I'm only inserting newline characters, though you can inster whole strings. Thus, it could be useful for inserting <br> tags in HTML or similar applications. I will wrap this text to 70 columns.\n\r";
char replace[] = "replace replace replace - all other text in the string was or will be changed!";
char alpha[] = "abcdefghijklmnopqrstuvwxyz";
char token_list_a[] = "this is a master token list delimited by spaces ";
char token_list_b []= "master list delim spaces this ";
int seconds = 98462;
int convert = 1342987462;
sprintf( buf, "\n\rDuration_to_str (long): %s\n\r", duration_to_str( seconds, TRUE ) );
send_to_char( buf, ch );
sprintf( buf, "Duration_to_str (short): %s\n\r", duration_to_str( seconds, FALSE ) );
send_to_char( buf, ch );
sprintf( buf, "\n\rInt_to_str (english): %s", int_to_str( convert, TRUE ) );
send_to_char( buf, ch );
sprintf( buf, "\n\rInt_to_str (digits): %s", int_to_str( convert, FALSE ) );
send_to_char( buf, ch );
sprintf( buf, "\n\rString before case conversion: %s\n\r", alpha );
send_to_char( buf, ch );
change_case_str( alpha, TRUE );
sprintf( buf, "\n\rConvert to upper: %s\n\r", alpha );
send_to_char( buf, ch );
change_case_str( alpha, FALSE );
sprintf( buf, "\n\rConverted back: %s\n\r", alpha );
send_to_char( buf, ch );
sprintf( buf, "\n\rGoing to find the text between the brackets <> in the string\n\r'%s'\n\r", str );
send_to_char( buf, ch );
sprintf( buf, "\n\rFind_between (between <>): %s\n\r", find_between( str, '<', '>' ) );
send_to_char( buf, ch );
sprintf( buf, "\n\rReplacing 'replace' within the string\n\r'%s'\n\r", replace );
send_to_char( buf, ch );
sprintf( buf, "\n\rReplace_str: %s\n\r", replace_str( str2, "replace", replace ) );
send_to_char( buf, ch );
send_to_char( "\n\rPrefix_str: Is 'woot' a prefix of 'wooty'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str( "woot", "wooty" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str: Is 'ra' a prefix of 'RAWR'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str( "ra", "RAWR" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str: Is 'you' a prefix of 'me'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str( "you", "me" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str: Is 'int' a prefix of 'uninteresting'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str( "int", "uninteresting" ) ? "Yes!" : "No!" );
send_to_char( "\n\rTesting case-sensitive version...\n\r", ch );
send_to_char( "\n\rPrefix_str_case: Is 'woot' a prefix of 'wooty'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str_case( "woot", "wooty" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str_case: Is 'ra' a prefix of 'RAWR'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str_case( "ra", "RAWR" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str_Case: Is 'you' a prefix of 'me'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str_case( "you", "me" ) ? "Yes!" : "No!" );
send_to_char( "\n\rPrefix_str_case: Is 'Int' a prefix of 'interesting'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", prefix_str_case( "Int", "interesting" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str: Is 'woot' == 'wooty'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str( "woot", "wooty" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str: Is 'rawr' == 'RAWR'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str( "rawr", "RAWR" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str: Is 'FooBar' == 'FOObar'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str( "FooBar", "FOObar" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str: Is 'Its alive!' == 'its alive!'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str( "Its alive!", "its alive!" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str_case: Is 'woot' == 'wooty'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str_case( "woot", "wooty" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str_case: Is 'rawr' == 'RAWR'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str_case( "rawr", "RAWR" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str_case: Is 'FooBar' == 'FOObar'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str_case( "FooBar", "FOObar" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str_case: Is 'Its alive!' == 'its alive!'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str_case( "Its alive!", "its alive!" ) ? "Yes!" : "No!" );
send_to_char( "\n\rCompare_str_case: Is 'I was the Turkey All Along' == 'I was the Turkey All Along'?\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_str_case( "I was the Turkey All Along", "I was the Turkey All Along" ) ? "Yes!" : "No!" );
sprintf(buf, "\n\rSearching for for 'STRING' within '%s'\n\r", replace );
send_to_char( buf, ch );
ch_printf( ch, "Times found (case-insensitive): %d\n\r", find_str( "STRING", replace, FALSE ) );
ch_printf( ch, "Times found (case-sensitive) : %d\n\r", find_str( "STRING", replace, TRUE ) );
ch_printf( ch, "\n\n\rFormating long string for display...\n\rOriginal length: %d\n\r", strlen(wrap) );
ch_printf( ch, "\n\rWordwrap_str:\n\r%s\n\r", wordwrap_str( wrap, 70, "\n" ) );
send_to_char( "Testing token handling functions..\n\r", ch );
ch_printf( ch, "\n\rTotal tokens in token_list_a: %d\n\r", total_tokens( token_list_a, ' ' ) );
ch_printf( ch, "\n\rTotal tokens in token_list_b: %d\n\r", total_tokens( token_list_b, ' ' ) );
ch_printf( ch, "\n\rSentence from token_list_a (and):\n\r%s\n\r", sentence_from_tokens( token_list_a, ' ', FALSE ) );
ch_printf( ch, "\n\rSentence from token_list_b (or)\n\r%s\n\r", sentence_from_tokens( token_list_b, ' ', TRUE ) );
send_to_char( "\n\rChecking to see if all tokens in list b are in list a (prefix checking on)\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_tokens( token_list_b, token_list_a, ' ', TRUE ) ? "All tokens in list b were in list a!" : "Woops, not all tokens in list b are in list a!" );
send_to_char( "\n\rChecking to see if all tokens in list b are in list a (prefix checking off)\n\r", ch );
ch_printf( ch, "\n\r%s\n\r", compare_tokens( token_list_b, token_list_a, ' ', FALSE ) ? "All tokens in list b were in list a!" : "Woops, not all tokens in list b are in list a!" );
grab_token( token_list_a, buf, ' ' );
ch_printf( ch, "\n\rFirst token in token_list_a was %s\n\r", buf );
grab_token( token_list_b, buf, ' ' );
ch_printf( ch, "\n\rFirst token in token_list_b was %s\n\r", buf );
if ( argument && argument[0] != '\0' )
{
ch_printf( ch, "\n\rExamining supplied token string (argument = '%s')\n\r", argument );
ch_printf( ch, "\n\rTotal tokens in argument: %d\n\r", total_tokens( argument, ' ' ) );
grab_token( argument, buf, ' ');
ch_printf( ch, "\n\rFirst token in argument was %s\n\r", buf );
}
}
(3.5)
If dlsym doesnt work on your system then you need to add do_teststrlib to their respective locations
in mud.h and tables.c.
(4) Compile. (make)
(5) When you are in-game use cedit to add do_teststrlib and run it to test all of the string functions.
Please note it is a lot of output, so be prepared to scroll.
Thats it! Have fun playing with your strings!
Statistics
==========
str_lib.c - 820 lines
str_lib.h - 91 lines
---
Contact
=======
Please send comments, suggestions, bugs, etc. to my e-mail.
~Odis
http:admin@ew.xidus.net