--- deliantra/server/plugins/cfperl/cfperl.xs 2006/02/03 19:49:32 1.5 +++ deliantra/server/plugins/cfperl/cfperl.xs 2006/02/08 03:46:15 1.15 @@ -1,36 +1,36 @@ /*****************************************************************************/ -/* That code is placed under the GNU General Public Licence (GPL) */ -/* (C)2001-2005 by Chachkoff Yann (Feel free to deliver your complaints) */ -/*****************************************************************************/ -/* CrossFire, A Multiplayer game for X-windows */ -/* */ -/* Copyright (C) 2000 Mark Wedel */ -/* Copyright (C) 1992 Frank Tore Johansen */ -/* Copyright (C) 2006 perl plugin by Marc Lehmann */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* CrossFire, A Multiplayer game for the X Window System */ /* */ /*****************************************************************************/ +/* + * This code is placed under the GNU General Public Licence (GPL) + * + * Copyright (C) 2001-2005 by Chachkoff Yann + * Copyright (C) 2006 by Marc Lehmann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include #include #include #undef save_long // clashes with libproto.h -#define PLUGIN_NAME "cfperl" +#define PLUGIN_NAME "perl" #define PLUGIN_VERSION "cfperl 0.0" #ifndef __CEXTRACT__ @@ -53,6 +53,8 @@ static f_plug_api registerGlobalEvent; static f_plug_api unregisterGlobalEvent; static f_plug_api systemDirectory; +static f_plug_api object_set_property; +static f_plug_api map_get_map; typedef struct { @@ -62,16 +64,48 @@ char message[1024]; int fix; int event_code; - char options[1024]; + char extension[1024]; // name field, should invoke specific perl extension + char options[1024]; // slaying field of event_connectors int returnvalue; } CFPContext; //static int current_command = -999; +static HV *obj_cache; static PerlInterpreter *perl; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// garbage collect some perl objects, if possible +// all objects no longer referenced and empty are +// eligible for destruction. +void +clean_obj_cache () +{ + int todo = 10; + do + { + I32 klen; + char *key; + HE *he = hv_iternext (obj_cache); + + if (he) + { + SV *sv = SvRV (hv_iterval (obj_cache, he)); + + // emopty and unreferened? nuke it + if (SvREFCNT (sv) == 1 && !HvFILL ((HV *)sv)) + { + hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD); + todo++; + } + } + else + break; + } + while (--todo); +} + static SV * newSVptr (void *ptr, const char *klass) { @@ -83,6 +117,27 @@ return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); } +static SV * +newSVptr_cached (void *ptr, const char *klass) +{ + SV *sv, **he; + + if (!ptr) + return &PL_sv_undef; + + he = hv_fetch (obj_cache, (char *)&ptr, sizeof (ptr), 0); + + if (he) + sv = *he; + else + { + sv = newSVptr (ptr, klass); + hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0); + } + + return newSVsv (sv); +} + static void clearSVptr (SV *sv) { @@ -130,7 +185,10 @@ break; case CFAPI_STRING: - sv = newSVpv (va_arg (args, char *), 0); + { + char *str = va_arg (args, char *); + sv = str ? newSVpv (str, 0) : &PL_sv_undef; + } break; case CFAPI_POBJECT: @@ -143,38 +201,38 @@ switch (*(int *)cf_object_get_property (obj, CFAPI_OBJECT_PROP_TYPE)) { case MAP: - sv = newSVptr (obj, "cf::object::map"); + sv = newSVptr_cached (obj, "cf::object::map"); break; case PLAYER: - sv = newSVptr (obj, "cf::object::player"); + sv = newSVptr_cached (obj, "cf::object::player"); break; default: - sv = newSVptr (obj, "cf::object"); + sv = newSVptr_cached (obj, "cf::object"); break; } } break; case CFAPI_PMAP: - sv = newSVptr (va_arg (args, object *), "cf::map"); + sv = newSVptr (va_arg (args, mapstruct *), "cf::map"); break; case CFAPI_PPLAYER: - sv = newSVptr (va_arg (args, object *), "cf::player"); + sv = newSVptr (va_arg (args, player *), "cf::player"); break; case CFAPI_PARCH: - sv = newSVptr (va_arg (args, object *), "cf::arch"); + sv = newSVptr (va_arg (args, archetype *), "cf::arch"); break; case CFAPI_PPARTY: - sv = newSVptr (va_arg (args, object *), "cf::party"); + sv = newSVptr (va_arg (args, partylist *), "cf::party"); break; case CFAPI_PREGION: - sv = newSVptr (va_arg (args, object *), "cf::region"); + sv = newSVptr (va_arg (args, region *), "cf::region"); break; default: @@ -189,7 +247,7 @@ ///////////////////////////////////////////////////////////////////////////// void -inject_event (CFPContext *context) +inject_event (const char *func, CFPContext *context) { dSP; @@ -198,9 +256,6 @@ PUSHMARK (SP); - EXTEND (SP, 2); - //PUSHs (sv_2mortal (newSViv (type))); - HV *hv = newHV (); #define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0) hv_context (CFAPI_POBJECT, ,who); @@ -210,21 +265,22 @@ hv_context (CFAPI_INT ,&,fix); hv_context (CFAPI_INT ,&,event_code); hv_context (CFAPI_STRING , ,options); + hv_context (CFAPI_STRING , ,extension); - PUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); + XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); PUTBACK; - int count = call_pv ("cf::inject_event", G_SCALAR | G_EVAL); + int count = call_pv (func, G_SCALAR | G_EVAL); SPAGAIN; + if (SvTRUE (ERRSV)) + LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV)); + context->returnvalue = count > 0 ? POPi : 0; PUTBACK; FREETMPS; LEAVE; - - if (SvTRUE (ERRSV)) - LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV)); } ///////////////////////////////////////////////////////////////////////////// @@ -261,15 +317,15 @@ int count = call_pv ("cf::inject_command", G_SCALAR | G_EVAL); SPAGAIN; + if (SvTRUE (ERRSV)) + LOG (llevError, "command '%s' callback evaluation error: %s", rtn_cmd.name, SvPV_nolen (ERRSV)); + int returnvalue = count > 0 ? POPi : -1; PUTBACK; FREETMPS; LEAVE; - if (SvTRUE (ERRSV)) - LOG (llevError, "command '%s' callback evaluation error: %s", rtn_cmd.name, SvPV_nolen (ERRSV)); - return returnvalue; } @@ -333,6 +389,9 @@ registerGlobalEvent = gethook (&rtype, hooktype, "cfapi_system_register_global_event"); unregisterGlobalEvent = gethook (&rtype, hooktype, "cfapi_system_unregister_global_event"); systemDirectory = gethook (&rtype, hooktype, "cfapi_system_directory"); + object_set_property = gethook (&rtype, hooktype, "cfapi_object_set_property"); + map_get_map = gethook (&rtype, hooktype, "cfapi_map_get_map"); + cf_init_plugin (gethook); /* Pick the global events you want to monitor from this plugin */ @@ -351,6 +410,7 @@ registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_FREE_OB, PLUGIN_NAME, globalEventListener); char *argv[] = { "", @@ -374,6 +434,10 @@ perl_free (perl); perl = 0; } + else + { + obj_cache = newHV (); + } return 0; } @@ -402,7 +466,11 @@ printf ("Unimplemented for now\n"); break; + case EVENT_MAPENTER: + case EVENT_MAPLEAVE: + case EVENT_FREE_OB: case EVENT_BORN: + case EVENT_REMOVE: context.activator = va_arg (args, object *); break; @@ -416,70 +484,51 @@ break; case EVENT_LOGIN: - pl = va_arg (args, player *); - context.activator = pl->ob; - buf = va_arg (args, char *); - if (buf != 0) - strcpy (context.message, buf); - break; - case EVENT_LOGOUT: pl = va_arg (args, player *); context.activator = pl->ob; buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); - break; - - case EVENT_REMOVE: - context.activator = va_arg (args, object *); + strncpy (context.message, buf, sizeof (context.message)); break; case EVENT_SHOUT: - context.activator = va_arg (args, object *); - buf = va_arg (args, char *); - if (buf != 0) - strcpy (context.message, buf); - break; - case EVENT_MUZZLE: - context.activator = va_arg (args, object *); - buf = va_arg (args, char *); - if (buf != 0) - strcpy (context.message, buf); - break; - case EVENT_KICK: context.activator = va_arg (args, object *); buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); break; - case EVENT_MAPENTER: - context.activator = va_arg (args, object *); - break; - - case EVENT_MAPLEAVE: - context.activator = va_arg (args, object *); + case EVENT_CLOCK: + clean_obj_cache (); break; - case EVENT_CLOCK: + case EVENT_TELL: break; case EVENT_MAPRESET: buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); - break; - - case EVENT_TELL: + strncpy (context.message, buf, sizeof (context.message)); break; } va_end (args); - inject_event (&context); + if (context.event_code == EVENT_FREE_OB) + { + SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (object *), 0); + + if (sv) + { + clearSVptr (sv); + SvREFCNT_dec (sv); + } + } + else + inject_event ("cf::inject_global_event", &context); rv = context.returnvalue; @@ -505,17 +554,18 @@ context.event_code = va_arg (args, int); context.activator = va_arg (args, object *); context.third = va_arg (args, object *); - buf = va_arg (args, char *); + buf = va_arg (args, char *); if (buf != 0) - strcpy (context.message, buf); + strncpy (context.message, buf, sizeof (context.message)); context.fix = va_arg (args, int); - strcpy (context.options, va_arg (args, char *)); + strncpy (context.extension, va_arg (args, char *), sizeof (context.extension)); + strncpy (context.options, va_arg (args, char *), sizeof (context.options)); context.returnvalue = 0; va_end (args); - inject_event (&context); + inject_event ("cf::inject_event", &context); rv = context.returnvalue; return &rv; @@ -542,7 +592,7 @@ { HV *stash = gv_stashpv ("cf", 1); - const struct { + static const struct { const char *name; IV iv; } *civ, const_iv[] = { @@ -803,12 +853,67 @@ const_iv (FLAG_IS_A_TEMPLATE) const_iv (FLAG_IS_BUILDABLE) const_iv (FLAG_AFK) + + const_iv (NDI_BLACK) + const_iv (NDI_WHITE) + const_iv (NDI_NAVY) + const_iv (NDI_RED) + const_iv (NDI_ORANGE) + const_iv (NDI_BLUE) + const_iv (NDI_DK_ORANGE) + const_iv (NDI_GREEN) + const_iv (NDI_LT_GREEN) + const_iv (NDI_GREY) + const_iv (NDI_BROWN) + const_iv (NDI_GOLD) + const_iv (NDI_TAN) + const_iv (NDI_MAX_COLOR) + const_iv (NDI_COLOR_MASK) + const_iv (NDI_UNIQUE) + const_iv (NDI_ALL) + + const_iv (F_APPLIED) + const_iv (F_LOCATION) + const_iv (F_UNPAID) + const_iv (F_MAGIC) + const_iv (F_CURSED) + const_iv (F_DAMNED) + const_iv (F_OPEN) + const_iv (F_NOPICK) + const_iv (F_LOCKED) + + const_iv (P_BLOCKSVIEW) + const_iv (P_NO_MAGIC) + const_iv (P_IS_ALIVE) + const_iv (P_NO_CLERIC) + const_iv (P_NEED_UPDATE) + const_iv (P_NO_ERROR) + const_iv (P_OUT_OF_MAP) + const_iv (P_NEW_MAP) + + const_iv (UP_OBJ_INSERT) + const_iv (UP_OBJ_REMOVE) + const_iv (UP_OBJ_CHANGE) + const_iv (UP_OBJ_FACE) + + const_iv (INS_NO_MERGE) + const_iv (INS_ABOVE_FLOOR_ONLY) + const_iv (INS_NO_WALK_ON) + const_iv (INS_ON_TOP) + const_iv (INS_BELOW_ORIGINATOR) + const_iv (INS_MAP_LOAD) + + const_iv (WILL_APPLY_HANDLE) + const_iv (WILL_APPLY_TREASURE) + const_iv (WILL_APPLY_EARTHWALL) + const_iv (WILL_APPLY_DOOR) + const_iv (WILL_APPLY_FOOD) }; for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); - const struct { + static const struct { const char *name; IV iv; } *event, event_list[] = { @@ -826,6 +931,7 @@ const_event (TRIGGER) const_event (CLOSE) const_event (TIMER) + const_event (MOVE) const_event (BORN) const_event (CLOCK) @@ -842,6 +948,7 @@ const_event (TELL) const_event (MUZZLE) const_event (KICK) + //const_event (FREE_OB) }; AV *av = get_av ("cf::EVENT", 1); @@ -849,7 +956,7 @@ for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; ) av_store (av, event->iv, newSVpv ((char *)event->name, 0)); - const struct { + static const struct { int dtype; const char *name; IV idx; @@ -975,9 +1082,6 @@ prop (CFAPI_STRING, OBJECT_PROP_ARCH_NAME) prop (CFAPI_INT, OBJECT_PROP_INVISIBLE) prop (CFAPI_INT, OBJECT_PROP_FACE) - prop (CFAPI_STRING, PLAYER_PROP_IP) - prop (CFAPI_POBJECT, PLAYER_PROP_MARKED_ITEM) - prop (CFAPI_PPARTY, PLAYER_PROP_PARTY) }; HV *prop_type = get_hv ("cf::PROP_TYPE", 1); @@ -992,14 +1096,17 @@ void LOG (int level, char *msg) + PROTOTYPE: $$ C_ARGS: level, "%s", msg char * cf_get_maps_directory (char *path) + PROTOTYPE: $ ALIAS: maps_directory = 0 char * mapdir () + PROTOTYPE: ALIAS: mapdir = 0 uniquedir = 1 @@ -1013,22 +1120,19 @@ int unused_type; RETVAL = (char *)systemDirectory (&unused_type, ix); } - OUTPUT: - RETVAL + OUTPUT: RETVAL int cf_find_animation (char *text) + PROTOTYPE: $ MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ -PROTOTYPES: DISABLE - SV * get_property (object *obj, int type, int idx) CODE: RETVAL = newSVcfapi (type, cf_object_get_property (obj, idx)); - OUTPUT: - RETVAL + OUTPUT: RETVAL SV * set_property (object *obj, int type, int idx, SV *newval) @@ -1041,6 +1145,12 @@ case CFAPI_LONG: cf_object_set_long_property (obj, idx, SvNV (newval)); break; + case CFAPI_DOUBLE: + { + int unused_type; + object_set_property (&unused_type, obj, idx, (double)SvNV (newval)); + } + break; case CFAPI_STRING: cf_object_set_string_property (obj, idx, SvPV_nolen (newval)); break; @@ -1048,6 +1158,16 @@ croak ("unhandled type '%d' in set_property '%d'", type, idx); } +void +inv (object *obj) + PROTOTYPE: $ + PPCODE: +{ + object *o; + for (o = obj->inv; o; o = o->below) + XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, o))); +} + int cf_object_get_resistance (object *op, int rtype) ALIAS: resistance = 0 @@ -1058,7 +1178,7 @@ void cf_object_move (object *op, object *originator, int dir) -void cf_object_apply (object *op, object *author, int flags) +void cf_object_apply (object *op, object *author, int flags = 0) void cf_object_apply_below (object *op) @@ -1130,58 +1250,119 @@ base_name (object *ob, int plural) CODE: RETVAL = cf_query_base_name (ob, plural); - OUTPUT: - RETVAL + OUTPUT: RETVAL MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ -object *cf_create_object () - ALIAS: new = 0 - -object *cf_create_object_by_name (const char *name) - ALIAS: new_from_name = 0 - -void cf_free_object (object *ob) +object *cf_create_object_by_name (const char *name = 0) + PROTOTYPE: ;$ + ALIAS: + create_object = 0 + new = 0 + CODE: + RETVAL = name ? cf_create_object_by_name (name) : cf_create_object (); + OUTPUT: + RETVAL void cf_fix_object (object *pl) + ALIAS: fix = 0 object *cf_insert_ob_in_ob (object *ob, object *where) +void rangevector (object *ob, object *other, int flags = 0) + PROTOTYPE: $$;$ + ALIAS: + direction = 1 + distance = 2 + CODE: +{ + rv_vector rv; + // get_rangevector uses these if the objects are not on the same map + // which is not the same as "on_same_map". + rv.distance_x = 32767; + rv.distance_y = 32767; + get_rangevector (ob, other, &rv, flags); + EXTEND (SP, 5); + if (!ix || ix == 2) PUSHs (newSVuv (rv.distance)); + if (!ix) PUSHs (newSViv (rv.distance_x)); + if (!ix) PUSHs (newSViv (rv.distance_y)); + if (!ix || ix == 1) PUSHs (newSViv (rv.direction)); + if (!ix) PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part)); +} + +bool on_same_map_as (object *ob, object *other) + CODE: + RETVAL = on_same_map (ob, other); + OUTPUT: RETVAL + MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_ player *player (object *op) CODE: RETVAL = cf_player_find (cf_query_name (op)); - OUTPUT: - RETVAL + OUTPUT: RETVAL -void cf_player_message (object *obj, char *txt, int flags = 0) +void cf_player_message (object *obj, char *txt, int flags = NDI_ORANGE | NDI_UNIQUE) object *cf_player_send_inventory (object *op) -void cf_player_set_marked_item(object *op, object *ob) +char *cf_player_get_ip (object *op) + ALIAS: ip = 0 + +object *cf_player_get_marked_item (object *op) + ALIAS: marked_item = 0 + +void cf_player_set_marked_item (object *op, object *ob) -void cf_player_set_party(object *op, partylist *party) +partylist *cf_player_get_party (object *op) + ALIAS: party = 0 + +void cf_player_set_party (object *op, partylist *party) MODULE = cf PACKAGE = cf::object::map PREFIX = cf_ -MODULE = cf PACKAGE = cf::player PREFIX = cf_ +MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ player *cf_player_find (char *name) + PROTOTYPE: $ void cf_player_move (player *pl, int dir) +# nonstandard +object *ob (player *pl) + CODE: + RETVAL = pl->ob; + OUTPUT: RETVAL + +player *first () + CODE: + RETVAL = first_player; + OUTPUT: RETVAL + +player *next (player *pl) + CODE: + RETVAL = pl->next; + OUTPUT: RETVAL + +void +list () + PPCODE: +{ + player *pl; + for (pl = first_player; pl; pl = pl->next) + XPUSHs (newSVcfapi (CFAPI_PPLAYER, pl)); +} -MODULE = cf PACKAGE = cf::map PREFIX = cf_ + +MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ SV * get_property (mapstruct *obj, int type, int idx) CODE: RETVAL = newSVcfapi (type, cf_map_get_property (obj, idx)); - OUTPUT: - RETVAL + OUTPUT: RETVAL SV * set_property (mapstruct *obj, int type, int idx, SV *newval) @@ -1195,10 +1376,22 @@ croak ("unhandled type '%d' in set_property '%d'", type, idx); } +mapstruct *new (int width, int height) + PROTOTYPE: + CODE: +{ + int unused_type; + RETVAL = map_get_map (&unused_type, 0, width, height); +} + OUTPUT: + RETVAL + mapstruct *cf_map_get_map (char *name) + PROTOTYPE: $ ALIAS: map = 0 mapstruct *cf_map_get_first () + PROTOTYPE: ALIAS: first = 0 object *cf_map_insert_object_there (mapstruct *where, object *op, object *originator, int flags) @@ -1210,11 +1403,51 @@ #int cf_map_get_flags (mapstruct* map, mapstruct** nmap, I16 x, I16 y, I16 *nx, I16 *ny) +void +at (mapstruct *obj, unsigned int x, unsigned int y) + PROTOTYPE: $$$ + INIT: + if (x >= MAP_WIDTH (obj) || y >= MAP_HEIGHT (obj)) XSRETURN_EMPTY; + PPCODE: +{ + object *o; + for (o = GET_MAP_OB (obj, x, y); o; o = o->above) + XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, o))); +} + +SV * +bot_at (mapstruct *obj, unsigned int x, unsigned int y) + PROTOTYPE: $$$ + ALIAS: + top_at = 1 + flags_at = 2 + light_at = 3 + move_block_at = 4 + move_slow_at = 5 + move_on_at = 6 + move_off_at = 7 + INIT: + if (x >= MAP_WIDTH (obj) || y >= MAP_HEIGHT (obj)) XSRETURN_UNDEF; + CODE: + switch (ix) + { + case 0: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_OB (obj, x, y)); break; + case 1: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_TOP (obj, x, y)); break; + case 2: RETVAL = newSVuv ( GET_MAP_FLAGS (obj, x, y)); break; + case 3: RETVAL = newSViv ( GET_MAP_LIGHT (obj, x, y)); break; + case 4: RETVAL = newSVuv ( GET_MAP_MOVE_BLOCK (obj, x, y)); break; + case 5: RETVAL = newSVuv ( GET_MAP_MOVE_SLOW (obj, x, y)); break; + case 6: RETVAL = newSVuv ( GET_MAP_MOVE_ON (obj, x, y)); break; + case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break; + } + OUTPUT: + RETVAL MODULE = cf PACKAGE = cf::arch PREFIX = cf_archetype_ -archetype*cf_archetype_get_first() +archetype *cf_archetype_get_first() + PROTOTYPE: ALIAS: first = 0 archetype *cf_archetype_get_next (archetype *arch) @@ -1231,14 +1464,15 @@ MODULE = cf PACKAGE = cf::party PREFIX = cf_party_ -const char *cf_party_get_name (partylist *party) - partylist *cf_party_get_first () + PROTOTYPE: ALIAS: first = 0 partylist *cf_party_get_next (partylist *party) ALIAS: next = 0 +const char *cf_party_get_name (partylist *party) + const char *cf_party_get_password (partylist *party) ALIAS: password = 0 @@ -1252,6 +1486,7 @@ MODULE = cf PACKAGE = cf::region PREFIX = cf_region_ region *cf_region_get_first () + PROTOTYPE: ALIAS: first = 0 const char *cf_region_get_name (region *reg)