/*1* IRC-II Copyright (C) 1990 Michael Sandroff and others,2* This file - Copyright (C) 1993,1995 Aaron Gifford3* This file written by Aaron Gifford and contributed to the EPIC4* project by Jeremy Nelson to whom it was contributed in Nov, 1993.5*6* Used with permission. See the COPYRIGHT file for copyright info.7*/8/*9DATE OF THIS VERSION:10---------------------11Sat Nov 27 23:00:20 MST 19931213NEW SINCE 20 NOV 1993:14----------------------15Two new functions were added: GETMATCHES() and GETRMATCHES()1617BUGS:18-----19I had a script that used these functions that caused ircII to crash20once or twice, but I have been unable to trace the cause or reproduce21the crash. I would appreciate any help or info if anyone else22experiences similar problems. This IS my first time using writing code23to work with ircII code.2425ARGUMENTS:26----------27array_name : A string of some sort (no spaces, case insensitive)28identifying an array, either an existing array, or a new array.2930item_number : A number or index into the array. All array items are31numbered beginning at zero and continuing sequentially. The32item number can be an existing item of an existing array, a33new item in an existing array (if the previous greatest item34number was 5, then the new item number must be 6, maintaining35the sequence), or a new item (must be item zero) in a new array.36data_... : Basically any data you want. It is stored internally as a37character string, and in indexed (more to come) internally38using the standard C library function strcmp().3940FUNCTIONS:41----------42SETITEM(array_name item_number data_to_be_stored)43Use SETITEM to set an existing item of an existing array to a new value,44to create a new value in an existing array (see note about item_number),45or to create a new array (see note about item_number above).46RETURNS: 0 (zero) if it successfully sets and existing item in the array471 if it successfully creates a new array482 if it successfully adds a new item to an existing array49-1 if it was unable to find the array specified (item_number > 0)50-2 if it was unable to find the item in an existing array51(item_number was too large)5253GETITEM(array_name item_number)54Use this to retrieve previously stored data.55RETURNS: the data requested56OR an empty string if the array did not exist or the item did not.5758NUMITEMS(array_name)59RETURNS: the number of items in the array60OR zero if the array name is invalid. Useful for auto-adding to61an array:62alias ADDDATA {63if (SETITEM(my-array $NUMITEMS(my-array) $*) >= 0) {64echo ADDED DATA65} {66echo FAILED TO ADD DATA67}68}6970DELITEM(array_name item_number)71This deletes the item requested from the array. If it is the last item72(item zero), it deletes the array. If there are items numbered higher73than this item, they will each be moved down. So if we had a 25 item74array called "MY-ARRAY" and deleted item 7, items 8 through 24 (remember75that a 25 item array is numbered 0 to 24) would be moved down and become76items 7 through 23.77RETURNS: Zero on success,78-1 if unable to find the array,79-2 if unable find the item.8081MATCHITEM(array_name pattern)82Searches through the items in the array for the item that best matches83the pattern, much like the MATCH() function does.84RETURNS: zero or a positive number which is the item_number of the match85OR -1 if unable to find the array,86OR -2 if no match was found in the array8788RMATCHITEM(array_name data_to_look_for)89This treats the items in the array as patterns, searching for the90pattern in the array that best matches the data_to_look_for, working91similarly to the RMATCH() function.92RETURNS: zero or a positive number which is the item_number of the match93OR -1 if unable to find the array,94OR -2 if no match was found in the array9596GETMATCHES(array_name pattern)97Seeks all array items that match the pattern.98RETURNS: A string containing a space-separated list of item numbers of99array elements that match the pattern, or a null string if no100matches were found, or if the array was not found.101102GETRMATCHES(array_name data_to_look_for)103Treats all array items as patterns, and seeks to find all patterns that104match the data_to_look_for.105RETURNS: A string containing a space-separated list of item numbers of106array elements that match the data, or a null string if no107matches were found, or if the array was not found.108109FINDITEM(array_name data_to_search_for)110This does a binary search on the items stored in the array and returns111the item number of the data. It is an EXACT MATCH search. It is highly112case sensitive, using C's strcmp() and not IRCII's caseless comparison113functions. I did it this way, because I needed it, so there! ;)114RETURNS: zero or a positive number on success -- this number IS the115item_number of the first match it found116OR -1 if unable to find the array,117OR -2 if the item was not found in the array.118119IGETITEM(array_name index_number)120This is exactly like GETITEM() except it uses a index number in the same121range as the item_number's. It returns the item that corresponds to the122internal alphabetized index that these functions maintain. Thus if you123access items 0 to 24 of "MY-ARRAY" with this function, you would observe124that the items returned came in an almost alphabetized manner. They125would not be truly alphabetized because the ordering is done using126strcmp() which is case sensitive.127RETURNS: the data to which the index refers128OR an empty string on failure to find the array or index.129130INDEXTOITEM(array_name index_number)131This converts an index_number to an item_number.132RETURNS: the item_number that corresponds to the index_number for133the array134OR -1 if unable to find the array,135OR -2 if the index_number was invalid136137ITEMTOINDEX(array_name item_number)138This converts an item_number to an index_number.139RETURNS: the index_number that corresponds to the item_number for140the array141OR -1 if unable to find the array,142OR -2 if the item_number was invalid143144DELARRAY(array_name)145This deletes all items in an array.146RETURNS: zero on success, -1 if it couldn't find the array.147148NUMARRAYS()149RETURNS: the number of arrays that currently exist.150151GETARRAYS()152RETURNS: a string consisting of all the names of all the arrays153separated by spaces.154155Thanks,156Aaron Gifford157Karll on IRC158<[email protected]>159160*/161/*162* FILE: alias.c163* WRITTEN BY: Aaron Gifford (Karll on IRC)164* DATE: Sat Nov 27 23:00:20 MST 1993165*/166167#include "irc.h"168static char cvsrevision[] = "$Id: array.c 81 2009-11-24 12:06:54Z keaston $";169CVS_REVISION(array_c)170171#include "array.h"172#include "ircaux.h"173#include "output.h"174#undef index175176#define MAIN_SOURCE177#include "modval.h"178179#define ARRAY_THRESHOLD 100180181typedef struct an_array_struct {182char **item;183long *index;184long size;185} an_array;186187static an_array array_info = {188NULL,189NULL,1900L191};192193static an_array *array_array = NULL;194195/*196* find_item() does a binary search of array.item[] using array.index[]197* to find an exact match of the string *find. If found, it returns the item198* number (array.item[item_number]) of the match. Otherwise, it returns a199* negative number. The negative number, if made positive again, and then200* having 1 subtracted from it, will be the item_number where the string *find201* should be inserted into the array.item[]. The function_setitem() makes use202* of this attribute.203*/204extern long find_item (an_array array, char *find)205{206long top, bottom, key, cmp;207208top = array.size - 1;209bottom = 0;210211while (top >= bottom)212{213key = (top - bottom) / 2 + bottom;214cmp = strcmp(find, array.item[array.index[key]]);215if (cmp == 0)216return key;217if (cmp < 0)218top = key - 1;219else220bottom = key + 1;221}222return -bottom - 1;223}224225/*226* insert_index() takes a valid index (newIndex) and inserts it into the array227* **index, then increments the *size of the index array.228*/229extern void insert_index (long **index, long *size, long newIndex)230{231long cnt;232233if (*size)234*index = (long *)RESIZE(*index, long, *size + 1);235else236{237*index = (long *)new_malloc(sizeof(long));238newIndex = 0;239}240241for (cnt = *size; cnt > newIndex; cnt--)242(*index)[cnt] = (*index)[cnt - 1];243(*index)[newIndex] = *size;244(*size)++;245}246247/*248* move_index() moves the array.index[] up or down to make room for new entries249* or to clean up so an entry can be deleted.250*/251extern void move_index (an_array *array, long oldindex, long newindex)252{253long temp;254255if (newindex > oldindex)256newindex--;257if (newindex == oldindex)258return;259260temp = array->index[oldindex];261262if (oldindex < newindex)263for (; oldindex < newindex; oldindex++)264array->index[oldindex] = array->index[oldindex + 1];265else266for(; oldindex > newindex; oldindex--)267array->index[oldindex] = array->index[oldindex - 1];268269array->index[newindex] = temp;270}271272/*273* find_index() attempts to take an item and discover the index number274* that refers to it. find_index() assumes that find_item() WILL always return275* a positive or zero result (be successful) because find_index() assumes that276* the item is valid, and thus a find will be successful. I don't know what277* value ARRAY_THRESHOLD ought to be. I figured someone smarter than I am278* could figure it out and tell me or tell me to abandon the entire idea.279*/280extern long find_index (an_array *array, long item)281{282long i = 0;283284if (array->size >= ARRAY_THRESHOLD)285{286i = find_item(*array, array->item[item]);287while (i >= 0 && !strcmp(array->item[array->index[i]], array->item[item]))288i--;289i++;290}291while(array->index[i] != item && i < array->size)292i++;293294if (i == array->size)295say("ERROR in find_index()");296return i;297}298299/*300* get_array() searches and finds the array referenced by *name. It returns301* a pointer to the array, or a null pointer on failure to find it.302*/303extern an_array * get_array (char *name)304{305long index;306307if (array_info.size && *name)308{309upper(name);310if ((index = find_item(array_info, name)) >= 0)311return &array_array[array_info.index[index]];312}313return NULL;314}315316317/*318* delete_array() deletes the contents of an entire array. It assumes that319* find_item(array_info, name) will succeed and return a valid zero or positive320* value.321*/322extern void delete_array (char *name)323{324char **ptr;325long cnt;326long index;327long item;328an_array *array;329330index = find_item(array_info, name);331item = array_info.index[index];332array = &array_array[item];333for (ptr=array->item, cnt=0; cnt < array->size; cnt++, ptr++)334new_free((char **)ptr);335new_free((char **)&array->item);336new_free((char **)&array->index);337338if (array_info.size > 1)339{340for(cnt = 0; cnt < array_info.size; cnt++)341if (array_info.index[cnt] > item)342(array_info.index[cnt])--;343move_index(&array_info, index, array_info.size);344array_info.size--;345for(ptr=&array_info.item[item], cnt=item; cnt < array_info.size; cnt++, ptr++, array++)346{347*ptr = *(ptr + 1);348*array = *(array + 1);349}350array_info.item = (char**)RESIZE(array_info.item, char *, array_info.size);351array_info.index = (long *)RESIZE(array_info.index, long, array_info.size);352RESIZE(array_array, an_array, array_info.size);353}354else355{356new_free((char **)&array_info.item);357new_free((char **)&array_info.index);358new_free((char **)&array_array);359array_info.size = 0;360}361}362363void delete_all_arrays(void)364{365char **ptr;366long index;367an_array *array;368#if 0369m_s3cat(&result, space, array_info.item[array_info.index[index]]);370#endif371for (index = 0; index < array_info.size; index++)372{373array = &array_array[index];374ptr = array->item;375while (array->size > 0)376{377new_free((char **)ptr);378ptr++;379array->size--;380}381new_free((char **)&array->item);382new_free((char **)&array->index);383}384for (index = 0; index < array_info.size; index++)385{386ptr = (char **)&array_info.item[index];387new_free(ptr);388ptr++;389}390new_free((char **)&array_info.item);391new_free((char **)&array_info.index);392new_free((char **)&array_array);393array_info.size = 0;394}395396/*397* Now for the actual alias functions398* ==================================399*/400401/*402* These are the same ones found in alias.c403*/404#define EMPTY empty_string405#define RETURN_EMPTY return m_strdup(EMPTY)406#define RETURN_IF_EMPTY(x) if (empty( x )) RETURN_EMPTY407#define GET_INT_ARG(x, y) {RETURN_IF_EMPTY(y); x = my_atol(safe_new_next_arg(y, &y));}408#define GET_FLOAT_ARG(x, y) {RETURN_IF_EMPTY(y); x = atof(safe_new_next_arg(y, &y));}409#define GET_STR_ARG(x, y) {RETURN_IF_EMPTY(y); x = new_next_arg(y, &y);RETURN_IF_EMPTY(x);}410#define RETURN_STR(x) return m_strdup(x ? x : EMPTY);411#define RETURN_INT(x) return m_strdup(ltoa(x));412413/*414* function_matchitem() attempts to match a pattern to the contents of an array415* RETURNS -1 if it cannot find the array, or -2 if no matches occur416*/417BUILT_IN_FUNCTION(function_matchitem)418{419char *name;420long index;421an_array *array;422long current_match;423long best_match = 0;424long match = -1;425426if ((name = next_arg(input, &input)) && (array = get_array(name)))427{428match = -2;429if (*input)430{431for (index = 0; index < array->size; index++)432{433if ((current_match = wild_match(input, array->item[index])) > best_match)434{435match = index;436best_match = current_match;437}438}439}440}441442RETURN_INT(match);443}444445BUILT_IN_FUNCTION(function_igetmatches)446{447char *result = NULL;448char *name = NULL;449long item;450an_array *array;451452if ((name = next_arg(input, &input)) &&453(array = get_array(name)) && *input)454{455if (*input)456{457for (item = 0; item < array->size; item++)458{459if (wild_match(input, array->item[item]) > 0)460m_s3cat(&result, space, ltoa(find_index(array, item)));461}462}463}464465if (!result)466RETURN_EMPTY;467468return result;469}470471/*472* function_listarray() attempts to list the contents of an array473* RETURNS "" if it cannot find the array474*/475BUILT_IN_FUNCTION(function_listarray)476{477char *name;478an_array *array;479long index;480char *result = NULL;481482if ((name = next_arg(input, &input)) && (array = get_array(name)))483{484for (index = 0; index < array->size; index++)485m_s3cat(&result, space, array->item[index]);486}487return result ? result : m_strdup(empty_string);488}489490/*491* function_getmatches() attempts to match a pattern to the contents of an492* array and returns a list of item_numbers of all items that match the pattern493* or it returns an empty string if not items matches or if the array was not494* found.495*/496BUILT_IN_FUNCTION(function_getmatches)497{498char *result = NULL;499char *name = NULL;500long index;501an_array *array;502503if ((name = next_arg(input, &input)) &&504(array = get_array(name)) && *input)505{506if (*input)507{508for (index = 0; index < array->size; index++)509{510if (wild_match(input, array->item[index]) > 0)511m_s3cat(&result, space, ltoa(index));512}513}514}515if (!result)516RETURN_EMPTY;517return result;518}519520/*521* function_rmatchitem() attempts to match the input text with an array of522* patterns, much like RMATCH()523* RETURNS -1 if it cannot find the array, or -2 if no matches occur524*/525BUILT_IN_FUNCTION(function_rmatchitem)526{527char *name = NULL;528long index;529an_array *array;530long current_match;531long best_match = 0;532long match = -1;533534if ((name = next_arg(input, &input)) && (array = get_array(name)))535{536match = -2;537if (*input)538{539for (index = 0; index < array->size; index++)540{541if ((current_match = wild_match(array->item[index], input)) > best_match)542{543match = index;544best_match = current_match;545}546}547}548}549RETURN_INT(match)550}551552/*553* function_getrmatches() attempts to match the input text with an array of554* patterns, and returns a list of item_numbers of all patterns that match the555* given text, or it returns a null string if no matches occur or if the array556* was not found.557*/558BUILT_IN_FUNCTION(function_getrmatches)559{560char *result = NULL;561char *name = NULL;562long index;563an_array *array;564565if ((name = next_arg(input, &input)) && (array = get_array(name)))566{567if (*input)568{569for (index = 0; index < array->size; index++)570{571if (wild_match(array->item[index], input) > 0)572m_s3cat(&result, space, ltoa(index));573}574}575}576577if (!result)578RETURN_EMPTY;579return result;580}581582/*583* function_numitems() returns the number of items in an array, or -1 if unable584* to find the array585*/586BUILT_IN_FUNCTION(function_numitems)587{588char *name = NULL;589an_array *array;590long items = 0;591592if ((name = next_arg(input, &input)) && (array = get_array(name)))593items = array->size;594595RETURN_INT(items);596}597598/*599* function_getitem() returns the value of the specified item of an array, or600* returns an empty string on failure to find the item or array601*/602BUILT_IN_FUNCTION(function_getitem)603{604char *name = NULL;605char *itemstr = NULL;606long item;607an_array *array;608char *found = NULL;609610if ((name = next_arg(input, &input)) && (array = get_array(name)))611{612if ((itemstr = next_arg(input, &input)))613{614item = my_atol(itemstr);615if (item >= 0 && item < array->size)616found = array->item[item];617}618}619RETURN_STR(found);620}621622/*623* function_setitem() sets an item of an array to a value, or creates a new624* array if the array doesn not already exist and the item number is zero, or625* it adds a new item to an existing array if the item number is one more than626* the prevously largest item number in the array.627* RETURNS: 0 on success628* 1 on success if a new item was added to an existing array629* 2 on success if a new array was created and item zero was set630* -1 if it is unable to find the array (and item number was not zero)631* -2 if it was unable to find the item (item < 0 or item was greater632* than 1 + the prevous maximum item number633*/634BUILT_IN_FUNCTION(function_setitem)635{636char *name = NULL;637char *itemstr = NULL;638long item;639long index = 0;640long oldindex;641an_array *array;642int result = -1;643644if ((name = next_arg(input, &input)))645{646if (strlen(name) && (itemstr = next_arg(input, &input)))647{648item = my_atol(itemstr);649if (item >= 0)650{651upper(name);652if (array_info.size && ((index = find_item(array_info, name)) >= 0))653{654array = &array_array[array_info.index[index]];655result = -2;656if (item < array->size)657{658oldindex = find_index(array, item);659index = find_item(*array, input);660index = (index >= 0) ? index : (-index) - 1;661move_index(array, oldindex, index);662new_free(&array->item[item]);663malloc_strcpy(&array->item[item], input);664result = 0;665}666else if (item == array->size)667{668array->item = (char **)RESIZE(array->item, char *, (array->size + 1));669array->item[item] = NULL;670malloc_strcpy(&array->item[item], input);671index = find_item(*array, input);672index = (index >= 0) ? index : (-index) - 1;673insert_index(&array->index, &array->size, index);674result = 2;675}676}677else678{679if (item == 0)680{681if (array_info.size)682RESIZE(array_array, an_array, (array_info.size + 1));683else684array_array = (an_array*)new_malloc(sizeof(an_array));685array = &array_array[array_info.size];686array->size = 1;687array->item = (char **)new_malloc(sizeof(char *));688array->index = (long *)new_malloc(sizeof(long));689array->item[0] = (char*) 0;690array->index[0] = 0;691malloc_strcpy(&array->item[0], input);692if (array_info.size)693array_info.item = (char **)RESIZE(array_info.item, char *, (array_info.size + 1));694else695array_info.item = (char **)new_malloc(sizeof(char *));696array_info.item[array_info.size] = NULL;697malloc_strcpy(&array_info.item[array_info.size], name);698insert_index(&array_info.index, &array_info.size, (-index) - 1);699result = 1;700}701}702}703}704}705RETURN_INT(result);706}707708/*709* function_getarrays() returns a string containg the names of all currently710* existing arrays separated by spaces711*/712BUILT_IN_FUNCTION(function_getarrays)713{714long index;715char *result = NULL;716717for (index = 0; index < array_info.size; index++)718if (!input || !*input || wild_match(input, array_info.item[array_info.index[index]]))719m_s3cat(&result, space, array_info.item[array_info.index[index]]);720721if (!result)722RETURN_EMPTY;723724return result;725}726727/*728* function_numarrays() returns the number of currently existing arrays729*/730BUILT_IN_FUNCTION(function_numarrays)731{732RETURN_INT(array_info.size)733}734735/*736* function_finditem() does a binary search and returns the item number of737* the string that exactly matches the string searched for, or it returns738* -1 if unable to find the array, or -2 if unable to find the item.739*/740BUILT_IN_FUNCTION(function_finditem)741{742char *name = NULL;743an_array *array;744long item = -1;745746if ((name = next_arg(input, &input)) && (array = get_array(name)))747{748if (*input)749{750item = find_item(*array, input);751item = (item >= 0) ? array->index[item] : -2;752}753}754RETURN_INT(item)755}756757/*758* function_ifinditem() does a binary search and returns the index number of759* the string that exactly matches the string searched for, or it returns760* -1 if unable to find the array, or -2 if unable to find the item.761*/762BUILT_IN_FUNCTION(function_ifinditem)763{764char *name = NULL;765an_array *array;766long item = -1;767768if ((name = next_arg(input, &input)) && (array = get_array(name)))769{770if (*input)771{772if ((item = find_item(*array, input)) < 0)773item = -2;774}775}776RETURN_INT(item)777}778779/*780* function_igetitem() returns the item referred to by the passed-in index781* or returns an empty string if unable to find the array or if the index was782* invalid.783*/784BUILT_IN_FUNCTION(function_igetitem)785{786char *name = NULL;787char *itemstr = NULL;788long item;789an_array *array;790char *found = NULL;791792if ((name = next_arg(input, &input)) && (array = get_array(name)))793{794if ((itemstr = next_arg(input, &input)))795{796item = my_atol(itemstr);797if (item >= 0 && item < array->size)798found = array->item[array->index[item]];799}800}801RETURN_STR(found)802}803804/*805* function_indextoitem() converts an index number to an item number for the806* specified array. It returns a valid item number, or -1 if unable to find807* the array, or -2 if the index was invalid.808*/809BUILT_IN_FUNCTION(function_indextoitem)810{811char *name = NULL;812char *itemstr = NULL;813long item;814an_array *array;815long found = -1;816817if ((name = next_arg(input, &input)) && (array = get_array(name)))818{819found = -2;820if ((itemstr = next_arg(input, &input)))821{822item = my_atol(itemstr);823if (item >= 0 && item < array->size)824found = array->index[item];825}826}827RETURN_INT(found)828}829830/*831* function_itemtoindex() takes an item number and searches for the index that832* refers to the item. It returns the index number, or -1 if unable to find833* the array, or -2 if the item was invalid.834*/835BUILT_IN_FUNCTION(function_itemtoindex)836{837char *name;838char *itemstr;839long item;840an_array *array;841long found = -1;842843if ((name = next_arg(input, &input)) && (array = get_array(name)))844{845found = -2;846if ((itemstr = next_arg(input, &input)))847{848item = my_atol(itemstr);849if (item >= 0 && item < array->size)850found = find_index(array, item);851}852}853RETURN_INT(found)854}855856/*857* function_delitem() deletes an item of an array and moves the contents of the858* array that were stored "above" the item down by one. It returns 0 (zero)859* on success, -1 if unable to find the array, -2 if unable to find the item.860* Also, if the item is the last item in the array, it deletes the array.861*/862BUILT_IN_FUNCTION(function_delitem)863{864char *name;865char *itemstr;866char **strptr;867long item;868long cnt;869long oldindex;870an_array *array;871long found = -1;872873if ((name = next_arg(input, &input)) && (array = get_array(name)))874{875found = -2;876if ((itemstr = next_arg(input, &input)))877{878item = my_atol(itemstr);879if (item >= 0 && item < array->size)880{881if (array->size == 1)882delete_array(name);883else884{885oldindex = find_index(array, item);886for(cnt = 0; cnt < array->size; cnt++)887if (array->index[cnt] > item)888(array->index[cnt])--;889move_index(array, oldindex, array->size);890new_free(&array->item[item]);891array->size--;892for(strptr=&(array->item[item]), cnt=item; cnt < array->size; cnt++, strptr++)893*strptr = *(strptr + 1);894array->item = (char**)RESIZE(array->item, char *, array->size);895array->index = (long*)RESIZE(array->index, long, array->size);896}897found = 0;898}899}900}901RETURN_INT(found)902}903904/*905* function_delarray() deletes the entire contents of the array using the906* delete_array() function above. It returns 0 on success, -1 on failure.907*/908BUILT_IN_FUNCTION(function_delarray)909{910char *name;911long found = -1;912913if ((name = next_arg(input, &input)) && (get_array(name)))914{915delete_array(name);916found = 0;917}918RETURN_INT(found)919}920/*921* function_ifindfirst() returns the first index of an exact match with the922* search string, or returns -2 if unable to find the array, or -1 if unable923* to find any matches.924*/925BUILT_IN_FUNCTION(function_ifindfirst)926{927char *name;928an_array *array;929long item = -1;930931if ((name = next_arg(input, &input)) && (array = get_array(name)))932{933if (*input)934{935if ((item = find_item(*array, input)) < 0)936item = -2;937else938{939while (item >= 0 && !strcmp(array->item[array->index[item]], input))940item--;941item++;942}943}944}945RETURN_INT(item)946}947948/*949* Given an array name with various strings in it, we wild_match() against950* the elements within the array. This allows parsing using % and *951* for wildcards. We return only the best match from the array, unlike952* getmatch() which returns ALL the matching items.953*/954955BUILT_IN_FUNCTION(function_gettmatch)956{957char *name;958an_array *array;959char *ret = NULL;960#if 0961<shade> gettmatch(users % user@host *) would match the userhost mask in the962second word of the array963#endif964if ((name = next_arg(input, &input)) && (array = get_array(name)))965{966if (*input)967{968int index, current_match;969int best_match = 0;970int match = -1;971for (index = 0; index < array->size; index++)972{973if ((current_match = wild_match(input, array->item[index])) > best_match)974{975match = index;976best_match = current_match;977}978}979if (match != -1)980ret = array->item[match];981982}983}984RETURN_STR(ret);985}986987BUILT_IN_FUNCTION(function_igetrmatches)988{989char *result = (char *) 0;990char *name = (char *) 0;991long item;992an_array *array;993994if ((name = next_arg(input, &input)) &&995(array = get_array(name)) && *input)996{997if (*input)998{999for (item = 0; item < array->size; item++)1000{1001if (wild_match(array->item[item], input) > 0)1002m_s3cat(&result, space, ltoa(find_index(array, item)));1003}1004}1005}10061007if (!result)1008RETURN_EMPTY;10091010return result;1011}101210131014