#include <learning.h> #define SAVE SAVEPATH +"search" mapping rooms, /* rooms[ keyword ] = array of rooms with this keyword */ objects, /* objects[ keyword ] = array of objects with this keyword */ keywords, /* keywords[ filename ] = array of keywords defined * by file */ functions; /* functions[ filename ] = array of functions defined * by object filename */ string *directories; /* Array holding the directories that still need * checking. * Used only while collecting information from * rooms in the domain. */ nosave string word; /* create() is the first function called in any object when it is * cloned. */ void create() { /* seteuid is needed for the save_object and restore_object calls */ seteuid( (string)master()->get_bb_uid() ); /* restore the saved values for the */ unguarded( (: restore_object, SAVE :) ); } /* create() */ /* Given words keywords chosen so far, * return ({ ({ keywords }), ({ rooms }), ({ objects }) }), * where keywords are all keywords that are in at least one of the rooms * or objects, objects are all objects having all words defined * and rooms are all rooms having all words defined. */ mixed get_keywords( string *words ) { string *found_words, *found_rooms, *found_objects, key, *value; if( sizeof( words ) ) { /* all files known */ found_objects = keys( keywords ); foreach( word in words ) { /* remove all files that haven't defined the keyword */ if( objects[ word ] ) { found_objects = filter_array( found_objects, (: member_array( $1, objects[ word ] ) != -1 :) ); } else { found_objects = ({ }); } } /* all files known */ found_rooms = keys( keywords ); foreach( word in words ) { /* remove all files that haven't defined the keyword */ if( rooms[ word ] ) { found_rooms = filter_array( found_rooms, (: member_array( $1, rooms[ word ] ) != -1 :) ); } else { found_rooms = ({ }); } } found_words = ({ }); foreach( word in found_rooms ) { found_words -= keywords[ word ]; /* remove duplicates */ found_words += keywords[ word ]; /* add new ones */ } foreach( word in found_objects ) { found_words -= keywords[ word ]; /* remove duplicates */ found_words += keywords[ word ]; /* add new ones */ } found_words -= words; /* remove those found already */ } else { found_rooms = ({ }); foreach( key, value in rooms ) { found_rooms -= value; /* remove duplicates */ found_rooms += value; /* add new ones */ } found_objects = ({ }); foreach( key, value in objects ) { found_objects -= value; /* remove duplicates */ found_objects += value; /* add new ones */ } found_words = keys( rooms ); found_words -= keys( objects ); found_words += keys( objects ); } return ({ found_words, found_rooms, found_objects }); } /* get_keyword() */ /* Get information for specific file. */ void update_info_for( string file ) { string *words, word; object obj; if( !catch( file->force_load() ) ) { obj = find_object( file ); words = obj->query_property( "commented functions" ); if( words ) { functions[ file ] = words; } words = obj->query_property( "keywords" ); if( words ) { keywords[ file ] = words; if( function_exists( "add_exit", obj ) ) { /* it's a room */ foreach ( word in words ) { if( rooms[ word ] ) { rooms[ word ] -= ({ file }); /* remove previous definition */ rooms[ word ] += ({ file }); /* add new */ } else { rooms[ word ] = ({ file }); } } } else { foreach ( word in words ) { if( objects[ word ] ) { objects[ word ] -= ({ file }); /* remove previous definition */ objects[ word ] += ({ file }); /* add new */ } else { objects[ word ] = ({ file }); } } } } if( !directories ) { /* This is a single room so save the new info */ unguarded( (: save_object, SAVE :) ); } } } /* update_info_for() */ /* This function does the same as the update command used on the room * Basically, it moves all users in the room, to the void, destructs the room * loads it again, and moves prople back again. */ void update_search( string room ) { object *obs; int i; obs = all_inventory( find_object( room ) ); i = sizeof( obs ); while( i-- ) { if ( userp( obs[ i ] ) ) { obs[ i ]->move( "/room/void" ); } else { obs = delete( obs, i, 1 ); } } room->dest_me(); room->force_load(); obs->move( room ); } /* update_search() */ /* collects the information from the next directory in line, adding new * subdirectories when found. */ void collect_one() { string dir; mixed dirs, file_info; dir = directories[ 0 ]; dirs = get_dir( dir, -1 ); if( dirs ) { foreach ( file_info in dirs ) { if( file_info[ 1 ] == -2 ) { /* it's a directory */ if( file_info[ 0 ] != "old" ) { /* ignore the files in the old dir */ directories = directories + ({ dir + file_info[ 0 ] +"/" }); } } else { /* it's a file */ if( ( sizeof( file_info[ 0 ] ) > 2 ) && ( file_info[ 0 ][ <2 .. <1 ] == ".c" ) ) { update_info_for( dir + file_info[ 0 ][ 0 .. <3 ] ); } } } } directories = directories[ 1 .. <1 ]; /* remove the dir that where just checked*/ if( find_call_out( "collect_one" ) == -1 && sizeof( directories ) ) { call_out( "collect_one", 3 ); } else if( !sizeof( directories ) ) { /* we are done so save */ /* tell me it's done */ tell_object( find_living( "olorin" ), "Collect finished.\n" ); directories = 0; /* and save it */ unguarded( (: save_object, SAVE :) ); /* this call is to restore all the keyword and function exits * to the first search and function rooms */ update_search( LEARNING +"search" ); update_search( LEARNING +"functions" ); } } /* collect_one */ void collect() { /* This function will start a run through all files in the subdirectories of * "/d/learning" and collect the needed information. */ rooms=([ ]); objects=([ ]); functions=([ ]); keywords=([ ]); directories=({ "/d/learning/" }); collect_one(); } /* collect() */ int query_collecting() { if( directories ) { return 1; } else { return 0; } } /* query_collecting() */ string find_room( string *words ) { object thing, *things; string word_mark; if( !sizeof( words ) ) return LEARNING +"search"; word_mark = implode( sort_array( words, 1 ), ", " ); things = children( SEARCH_ROOM ) - ({ find_object( SEARCH_ROOM ) }); foreach ( thing in things ) { if ( (string)thing->query_marker() == word_mark ) return file_name( thing ); } thing = clone_object( SEARCH_ROOM ); thing->set_marker( word_mark, words ); return file_name( thing ); } /* find_room() */ string find_function_room( string word ) { object thing, *things; if( !word ) return LEARNING +"functions"; things = children( FUNCTION_ROOM ) - ({ find_object( FUNCTION_ROOM ) }); foreach ( thing in things ) { if ( (string)thing->query_marker() == word ) return file_name( thing ); } thing = clone_object( FUNCTION_ROOM ); thing->set_marker( word ); return file_name( thing ); } /* find_function_room() */ string *query_functions() { string *functions_found, key, *value; functions_found = ({ }); foreach ( key, value in functions ) { functions_found -= value; /* remove duplicates */ functions_found += value; } return sort_array( functions_found, 1 ); } /* query_functions() */ string *query_rooms_with_function( string word ) { string *rooms_found, key, *value; rooms_found = ({ }); foreach ( key, value in functions ) { if ( member_array( word, value ) != -1 ) rooms_found += ({ key }); } return rooms_found; } /* query_rooms_with_function() */