dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/*  -*- LPC -*-  */
/*
 * $Locker:  $
 * $Id: autodoc_handler.c,v 1.19 1999/10/26 00:57:49 pinkfish Exp $
 * 
*/
/**
 * Documentation system for removing documentation from source files.
 * <p>
 * The documentation will be created in the directory /doc/autodoc.  Extra
 * documentation should be placed into the other help directories and will
 * be accessed via the help system.  The html documentation will be placed
 * into the /www/autodoc directory.  The files in theses directories will
 * be named with the '/'s replaced with '.'s.  ie: /obj/handlers/room_handler.c
 * would be in the file /doc/autodoc/obj.handlers.room_handler.c and
 * /www/autodoc/obj.handlers.room_handler.c.html.  An index of the methods
 * and object names will be generated from the input files and linked into the
 * help system.  An alphabetical index will also be produced that is linked
 * to the html stuff.
 * <p>
 * The first comment which follows the comment format below and occurs right
 * before a function will be used as the documentation for that function.  The
 * comment must start with two '*'s to distinguish it from a normal comment.
 * A special tag at the start of one of the first comments in the file will
 * signify that it is a comment for the class.
 * <p>
 * Only comments before a real function declaration will be used, comments
 * before a predeclaration will be ignored.
 * <p>
 * Any function which is not declared as private and does not have the @ignore
 * tag in its description will be placed into the resulting documentation
 * file.  This will be done even if no comment was found.
 * <p>
 * In the text part of the comment the main section is a free form
 * documentation, it is merely a description of the whole function.  After
 * this several tags can be added to the comment which allows other things
 * to be documented.  All the text after the tag is taken as part of that
 * tags information.  The main tag should never actually be used, it
 * is implied as being the tag associated with the first section of
 * comment.
 * <p>
 * HTML tags will be used in the comments to allow certain things to
 * happen.  The tags 'p', 'b', 'i', 'code', 'ul', 'ol', 'dl', 'dd', 'dt', 'pre'
 * and 'li' will be supported.
 * <p>
 * The sequences '\\/', '\\\\' and '\<' will be processed by the comment
 * handling code so that they do not get placed into the output code.
 * <p>
 * White space is ignored...  Both html and dw nroff format files will be
 * created from the documentation maker.
 * <p>
 * The supported tags are:
 * <dl>
 * <dt>@param
 * <dd>Specify the parameter and what it does.  This should be one short
 *     sentance only.  There needs to be one of these for every
 *     parameter, the first word of the sentance is the name of the 
 *     paramater and the rest is the descrption.  There should be no full
 *     stop on the end of the sentance.
 * <dt>@member
 * <dd>This is used with classes and defines the members of the class.  The
 *     definition is the same as for the @param element above.
 * <dt>@return
 * <dd>Specify what the return value is.  This should be one short
 *     sentance only.  Theres should only be one of these in every
 *     function.  There should be no full stop on the end of the sentance.
 * <dt>@see
 *   <dd>Specify an object or function to see.  The format must be one of:
 *   <ul>
 *   <li> object_name<br><i>@see /global/new_parse</i>
 *   <li> function_name()<br><i>@see frog()</i>
 *   <li> object_name->function_name()<br><i>@see /global/new_parse->add_command()</i>
 *   <li> efun::name()<br><i>@see efun::sort_array()</i>
 *   <li> help::name<br>@see help::effects
 *   </ul>
 * <dt>@ignore
 *   <dd>Do not document this function, the whole comment is ignored.
 * <dt>@main
 *   <dd>The main documentation section.
 * <dt>@classification
 *    <dd>Used in the effects files to classifiy the effect.  So a tree
 *      of the classifications can be derived.
 * <dt>@index
 *        <dd>Adds in a new index refernece on this name.  This should be one
 *            word only.
 * <dt>@change
 *   <dd>Placed in the class documentation to reference a change list.
 *            First line after the tag is the date and the author and
 *            then follows a description of the change.
 * <dt>@example
 *   <dd>If you wish to embed an example in the code.
 * <dt>@started
 *   <dd>When the file was started.
 * <dt>@author
 *   <dd>The author of the file.
 * </dl>
 *
 * The output format will look something like the API documentation for
 * java.  If you have not seen this before, go to http://www.javasoft.com
 * and look in the JDK and then the API section.
 * <p>
 * Comment format:
 * <pre>
 * /\**
 *  *  <text>
 *  *    ..
 *  *  <text>
 *  *
 *  *\/
 * </pre>
 *
 * ie: it starts with a /\** and ends with a *\/ on a line by themselves and
 * every intervening line has a * at the start.  By using a \\ you can
 * make characters escaped.  This means they are not processed by
 * the internal system, so to make a end comment appear inside a
 * the text you go : *\\/
 *
 * @example
 * inherit "/std/object";
 *
 * /\**
 *  *   This class is a nice shade of blue and allows all other shades of
 *  *   green and yellow to mix well.
 *  * @see yellow
 *  * @see blue
 *  * @change 12/3/97 Pinkfish
 *  *    Pushed some of the yellow stuff down a hole and ate a bagel.
 *  *\/
 *
 * /\**
 *  * This method mixes the green in with our blue.
 *  * @param  green   the green object to mix.
 *  *\/
 * void mixGreen(object green) {
 *   /\* Something wild and exciting! *\/
 * } /\* mixGreen() *\/
 *
 * /\**
 *  * This method mixes the yellow in with our blue.
 *  * @param  yellow the yellow object to mix.
 *  * @return returns a TRUE or FALSE depending on if the mix succeeded.
 *  * @example
 *  *   mixYellow(12);
 *  *\/
 * int mixYellow(object yellow) {
 * } /\* mixYellow() *\/
 *
 * @index autodoc
 * @see /obj/handlers/autodoc/autodoc_file
 * @see /obj/handlers/autodoc/autodoc_nroff
 * @see /obj/handlers/autodoc/autodoc_html
 * @author Pinkfish
 * @started Tue Oct 28 13:25:09 EST 1997
 *
 */

#include <autodoc.h>

#define MAIN_FILE 0
#define INDEX_FILE 1

#define SAVE_FILE (SAVE_DIR "main_rubbish")

string *files;
int file_pos;
int something_changed;
int last_created_index;
nosave function *filters;
nosave int call_id;
nosave mapping summary_map;
nosave mixed *extra_indexes;
mapping help_map;

private void create_nroff_file(object ob, int type);
private void create_html_file(object ob, int type);
private void after_thingy(int no_index);
private void start_processing();
private void do_parse_next_file();
private void create_index();
private void add_to_index(object ob);
private void load();
private void save();
string *query_files();
int remove_file(string fname);

void create() {
   seteuid(getuid());
   filters = ({ (: create_nroff_file($1, $2) :),
                (: create_html_file($1, $2) :) });
   file_pos = 0;
   something_changed = 0;
   files = ({ });
   load();
   do_parse_next_file();
   /* For testing... */
   //create_index();
} /* create() */

private void create_nroff_file(mixed ob, int type) {
   string fname;
   mixed *stuff;
   mixed *index_stuff;
   int i;

   if (type == MAIN_FILE) {
      /* Now we create the nroff file... */
      fname = replace(ob->query_file_name(), "/", ".");
      if (fname[0] == '.') {
         fname = fname[1..];
      }
      rm(NROFF_DOC_DIR + fname);
      AUTODOC_NROFF->create_nroff_file(ob, NROFF_DOC_DIR + fname);
   } else if (type == INDEX_FILE) {
      /* Create an index file... */
      /* Divide into letters... */
      index_stuff = ob;
      stuff = map(query_files(), function (string name) {
           string *bits;

           bits = explode(name, "/");
           return ({ bits[sizeof(bits)-1], name });
        } );
      stuff = unique_array(index_stuff + stuff, (: lower_case($1[0])[0] :));
      for (i = 0; i < sizeof(stuff); i++) {
         fname = NROFF_DOC_DIR + "index_" + lower_case(stuff[i][0][0][0..0]);
         AUTODOC_NROFF->create_nroff_index_file(stuff[i], fname);
      }
   }
} /* create_nroff_file() */

private void create_html_file(mixed ob, int type) {
   string fname;
   mixed *stuff;
   mixed *index_stuff;
   int i;
   mapping chars;

   if (type == MAIN_FILE) {
      /* Now we create the nroff file... */
      fname = replace(ob->query_file_name(), "/", ".");
      if (fname[0] == '.') {
         fname = fname[1..];
      }
      fname += ".html";
      rm(HTML_DOC_DIR + fname);
      AUTODOC_HTML->create_html_file(ob, HTML_DOC_DIR + fname);
   } else if (type == INDEX_FILE) {
      /* Create an index file... */
      index_stuff = ob;
      stuff = map(query_files(), function (string name) {
           string *bits;

           bits = explode(name, "/");
           return ({ bits[sizeof(bits)-1], name, "", summary_map[name] });
        } );
      stuff = unique_array(index_stuff + stuff, (: lower_case($1[0])[0] :));
      chars = ([ ]);
      for (i = 0; i < sizeof(stuff); i++) {
         fname = "index_" + lower_case(stuff[i][0][0][0..0]) + ".html";
         rm(HTML_DOC_DIR + fname);
         AUTODOC_HTML->create_html_index_file(stuff[i], stuff[i][0][0][0..0],
                                       HTML_DOC_DIR + fname);
         reset_eval_cost();
         chars[capitalize(stuff[i][0][0][0..0])] =  fname;
      }
      /* The differnt sorts of index will be genertated in the html file */
      fname = HTML_DOC_DIR; // + "index.html";
      //rm(fname);
      AUTODOC_HTML->create_main_index(chars, fname);
   }
} /* create_html_file() */

private void after_thingy(int no_index) {
   int i;

   if (no_index) {
      printf("Finished recreating the documentation for %O\n",
              previous_object()->query_file_name(),
             previous_object());
   }

   if (previous_object()->query_changed()) {
      something_changed = 1;
   }

   if (previous_object()->query_num_failed_tries() > 1) {
      /*
       * This means that the file has been deleted...  Argh!  Auto remove
       * it and log it.
       */
      remove_file(files[file_pos - 1]);
      //log_file("AUTODOC", ctime(time()) + ": Removing: " + files[file_pos - 1] + " \n");
   } else if (previous_object()->query_changed() || no_index) {
      //log_file("AUTODOC", ctime(time()) + ": Parsing: " + files[file_pos - 1] + " \n");
      for (i = 0; i < sizeof(filters); i++) {
         call_out((: evaluate($1, $2, $3) :), 0, filters[i],
                  previous_object(), MAIN_FILE);
      }
   }

   call_out((: $1->dest_me() :), 20, previous_object());
   save();
} /* after_thingy() */

private void do_parse_next_file() {
   /* Give it a minute to do this file... */
   call_id = call_out((: start_processing() :), 60);
   if (file_pos >= sizeof(files)) {
      file_pos = 0;
   }
   new(AUTODOC_FILE)->parse_file(files[file_pos++], (: after_thingy(0) :));
} /* do_parse_next_file() */
 
private void start_processing() {
   if (sizeof(files) == 0) {
      return ;
   }

   /* Ok, now we skip onto the next file and zoom it... */
   if (last_created_index + SAVE_INDEX_DELAY < time()) {
      if (something_changed) {
         call_out( (: create_index() :), 2);
      }
      something_changed = 0;
      save();
   }

   call_id = call_out((: do_parse_next_file() :), 360);
} /* start_processing() */

private string query_short_args_def(mixed *args) {
   string ret;
   int i;

   ret = "";
   for (i = 0; i < sizeof(args); i += 2) {
      if (i != 0) {
         ret += ", ";
      }
      ret += implode(args[AUTO_ARGS_TYPE], " ");
   }
   return "(" + ret + ")";
} /* query_short_args_def() */

/*
 * This will add it into the help array stuff too..
 */
private string *process_stuff(string name,
                              string fname,
                              string fn,
                              mapping docs) {
   string blue;
   int i;
   int end;
   mixed *ret;
   mapping fluff;

   if (name != "create" && name != "setup" && name != "init") {
      if (help_map[name]) {
         help_map[name] += ({ fn });
      } else {
         help_map[name] = ({ fn });
      }
   }
   if (docs[name]) {
      if (arrayp(docs[name])) {
         /* Its a function! */
         fluff = docs[name][AUTO_DOCS];
         ret =  ({ name, fname, query_short_args_def(docs[name][AUTO_ARGS]) });
      } else {
         ret = ({ name, fname, "" });
         fluff = docs[name];
      }
   } else {
      ret = ({ name, fname, "" });
      if (mapp(docs)) {
         fluff = docs;
      } else {
         fluff = ([ ]);
      }
   }
   if (fluff["main"]) {
      blue = implode(fluff["main"], "\n");
      end = strlen(blue);
      i = strsrch(blue, ".");
      if (i > 0) {
         end = i;
      }
      i = strsrch(blue, "!");
      if (i > 0 && i < end) {
         end = i;
      }
      i = strsrch(blue, "?");
      if (i > 0 && i < end) {
         end = i;
      }
      blue = blue[0..end];
   }
   ret += ({ blue });
   if (fluff["index"]) {
      foreach (blue in fluff["index"]) {
         blue = replace(blue, ({ " ", "", "\n", "" }));
         if (help_map[blue]) {
            help_map[blue] += ({ fn });
         } else {
            help_map[blue] = ({ fn });
         }
         extra_indexes += ({ ({ blue, fname, "", ret[AUTO_INDEX_SUMMARY] }) });
      }
   }
   return ret;
} /* process_stuff() */

private void create_index() {
   int i;
   mixed *index_stuff;
   mixed *rabbit;
   string fname;
   string fn;
   string *bits;
   object parse;

   //log_file("AUTODOC", ctime(time()) + ": Created index.\n");
   /* Build up the list... */
   index_stuff = ({ });
   help_map = ([ ]);
   extra_indexes = ({ });
   summary_map = ([ ]);
   parse = clone_object(AUTODOC_FILE);
   for (i = 0; i < sizeof(files); i++) {
      /* Do not process it...  Merely load it from disk */
      parse->parse_file(files[i], 0, 1);
      fname = parse->query_file_name();
      if (fname) {
         fn = replace(fname, "/", ".");
         if (fn[0] == '.') {
            fn = fn[1..];
         }
         fn = NROFF_DOC_DIR + fn;
         bits = explode(fname[0..strlen(fname)-3], "/");
         rabbit = process_stuff(bits[sizeof(bits) - 1], "", fn,
                                parse->query_main_docs());
         if (rabbit[AUTO_INDEX_SUMMARY]) {
            summary_map[fname] = rabbit[AUTO_INDEX_SUMMARY];
         } else {
            map_delete(summary_map, fname);
         }
         /* We loaded it... */
         index_stuff += map(keys(parse->query_public_functions()),
                            (: process_stuff($1, $(fname), $(fn),
                               $(parse)->query_public_functions()) :) );
         index_stuff += map(keys(parse->query_protected_functions()),
                            (: process_stuff($1, $(fname), $(fn),
                               $(parse)->query_protected_functions()) :) );
         index_stuff += map(keys(parse->query_class_docs()),
                            (: process_stuff($1, $(fname), $(fn),
                               $(parse)->query_class_docs()) :) );
         if (sscanf(fname, "%*s.h") == 1) {
            index_stuff += map(keys(parse->query_define_docs()),
                               (: process_stuff($1, $(fname), $(fn),
                               $(parse)->query_define_docs()) :) );
         }
      }
      reset_eval_cost();
   }
   index_stuff += extra_indexes;
   extra_indexes = ({ });

   /* Don't call this out.  We would be copying huge arrays around.  Eeek. */
   for (i = 0; i < sizeof(filters); i++) {
      reset_eval_cost();
      catch(evaluate(filters[i], index_stuff, INDEX_FILE));
   }
   summary_map = ([ ]);
   last_created_index = time();
   save();
} /* create_index() */

/**
 * Recreate documentation for one fiel immediately.  This does not update
 * the index, it merely creates the base files for this file.  It does it
 * at a random delay of up to 30 seconds.
 *
 * @param fname the file name to update
 */
int recreate_documentation(string fname) {
   object ob;

   if (member_array(fname, files) != -1) {
      ob = clone_object(AUTODOC_FILE);
      ob->parse_file(fname, (: after_thingy(1) :));
      return 1;
   }
   return 0;
} /* recreate_documentation() */

/**
 * Regenerate the index files.
 */
void recreate_indexes() {
   unguarded( (: create_index() :));
} /* recreate_indexes() */

/**
 * Adds a file into the list of files to process for autodocumentation.
 * This file will be processed every time around in the autodocumentation
 * loop to check to see if it has been changed and the results will be
 * placed into the index.  It automaticly calls recreate_documentation
 * in random(60) seconds.
 *
 * @see recreate_documentation()
 *
 * @param fname the name of the file to add
 *
 * @return 1 if the add succeeds, 0 otherwise.
 */
int add_file(string fname) {
   fname = "/" + implode(explode(fname, "/") - ({ "" }), "/");
   if (member_array(fname, files) == -1) {
      if (sizeof(unguarded( (: stat($(fname)) :) ))) {
         files += ({ fname });
         save();
         if (sizeof(files) == 1) {
            start_processing();
         } else {
            call_out((: recreate_documentation($1) :), random(60), fname);
         }
         return 1;
      }
   }
   return 0;
} /* add_file() */

/**
 * Removes a file from the list of files to be processed for autodocumentation.
 *
 * @param fname the name of the file to remove
 *
 * @return 1 if the remove succeeds, 0 otherwise.
 */
int remove_file(string fname) {
   string fn;
   string dfn;
   string *our_files;
 
   if (member_array(fname, files) != -1) {
      files -= ({ fname });
      file_pos = 0;

      /* Delete the files associated with it, start with the html files. */
      fn = HTML_DOC_DIR + replace(fname, "/", ".");
      unguarded((: rm($(fn)) :));
      /* Delete the nroff files. */
      fn = NROFF_DOC_DIR + replace(fname, "/", ".");
      unguarded((: rm($(fn)) :));
      /* Delete the nroff single function files. */
      fn = NROFF_DOC_SINGLE + fname[0..<3] + "/";
      our_files = get_dir(fn);
      if (sizeof(our_files)) {
         foreach (dfn in our_files) {
            dfn =  fn + dfn;
            unguarded( (: rm($(dfn)) :) );
         }
      }
      /* Remove the directory if it exists. */
      if (file_size(fn[0..<2]) != -1) {
         unguarded((: rm($(fn[0..<2])) :));
      }

      save();
      if (!sizeof(files)) {
         remove_call_out(call_id);
      }
      return 1;
   }
   return 0;
} /* remove_file() */

private void load() {
   unguarded( (: restore_object( SAVE_FILE ) :) );
} /* load() */

private void save() {
   unguarded( (: save_object( SAVE_FILE ) :) );
} /* save() */

/**
 * Returns the list of files we are current processing.
 *
 * @return an array of strings being the file names
 */
string *query_files() { return files; }

/**
 * Returns the help mapping.  This is the mapping from function names to
 * files.  Each element in the mapping referes to an array of file
 * names which contain the function or define.
 *
 * @return a mapping of arrays of files
 */
mapping query_help_map() { return help_map; }

/**
 * This method returns the file name of the help for the specified
 * function in the specified file.
 * @param file the file name to find the help in
 * @param func the function to look for help on in the file
 * @return the full path to the help file, 0 if it does not exist
 */
string query_help_on(string file, string func) {
   if (file[0] == '/') {
      file = file[1..];
   }
   if (sscanf(file, "%*s.c") == 1) {
      file = file[0..<3];
   }
   file = NROFF_DOC_SINGLE + file + "/" + func;
   if (file_size(file) > 0) {
      return file;
   }
   return 0;
} /* query_help_on() */

/**
 * Retuirns the mapping of file names to a summary.  This is only
 * valid during the index creation cycle of the documentation generation
 * system.  It is used to create a more useful index page.
 * @return the mapping of file names to summarys
 */
mapping query_summary_map() { return summary_map; }

/**
 * This method tells us if the file is currently in the autodoc set.
 * @return 1 if the file is found, 0 if not
 */
int is_autodoc_file(string name) {
   return member_array(name, files) != -1;
} /* is_autodoc_file() */