struct t_hashtable * weechat_guile_alist_to_hashtable (SCM alist, int hashtable_size) { struct t_hashtable *hashtable; int length, i; SCM pair; hashtable = weechat_hashtable_new (hashtable_size, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; length = scm_to_int (scm_length (alist)); for (i = 0; i < length; i++) { pair = scm_list_ref (alist, scm_from_int (i)); weechat_hashtable_set (hashtable, scm_i_string_chars (scm_list_ref (pair, scm_from_int (0))), scm_i_string_chars (scm_list_ref (pair, scm_from_int (1)))); } return hashtable; }
/*=gfunc in_p * * what: test for string in list * general_use: * exparg: test-string, string to look for * exparg: string-list, list of strings to check,, list * * doc: Return SCM_BOOL_T if the first argument string is found * in one of the entries in the second (list-of-strings) argument. =*/ SCM ag_scm_in_p(SCM obj, SCM list) { int len; size_t lenz; SCM car; char const * pz1; if (! AG_SCM_STRING_P(obj)) return SCM_UNDEFINED; pz1 = scm_i_string_chars(obj); lenz = AG_SCM_STRLEN(obj); /* * If the second argument is a string somehow, then treat * this as a straight out string comparison */ if (AG_SCM_STRING_P(list)) { if ( (AG_SCM_STRLEN(list) == lenz) && (strncmp(pz1, scm_i_string_chars(list), lenz) == 0)) return SCM_BOOL_T; return SCM_BOOL_F; } len = (int)scm_ilength(list); if (len == 0) return SCM_BOOL_F; /* * Search all the lists and sub-lists passed in */ while (len-- > 0) { car = SCM_CAR(list); list = SCM_CDR(list); /* * This routine is listed as getting a list as the second * argument. That means that if someone builds a list and * hands it to us, it magically becomes a nested list. * This unravels that. */ if (! AG_SCM_STRING_P(car)) { if (ag_scm_in_p(obj, car) == SCM_BOOL_T) return SCM_BOOL_T; continue; } if ( (AG_SCM_STRLEN(car) == lenz) && (strncmp(pz1, scm_i_string_chars(car), lenz) == 0) ) return SCM_BOOL_T; } return SCM_BOOL_F; }
/*=gfunc string_tr * * what: convert characters with new result * general_use: * * exparg: source, string to transform * exparg: match, characters to be converted * exparg: translation, conversion list * * doc: This is identical to @code{string-tr!}, except that it does not * over-write the previous value. =*/ SCM ag_scm_string_tr(SCM Str, SCM From, SCM To) { size_t lenz = AG_SCM_STRLEN(Str); SCM res = AG_SCM_STR2SCM(scm_i_string_chars(Str), lenz); return ag_scm_string_tr_x(res, From, To); }
unsigned long scm_i_string_hash (SCM str) { size_t len = scm_i_string_length (str); if (scm_i_is_narrow_string (str)) return narrow_string_hash ((const scm_t_uint8 *) scm_i_string_chars (str), len); else return wide_string_hash (scm_i_string_wide_chars (str), len); }
/*=gfunc time_string_to_number * * what: duration string to seconds * general_use: * exparg: time_spec, string to parse * * doc: Convert the argument string to a time period in seconds. * The string may use multiple parts consisting of days, hours * minutes and seconds. These are indicated with a suffix of * @code{d}, @code{h}, @code{m} and @code{s} respectively. * Hours, minutes and seconds may also be represented with * @code{HH:MM:SS} or, without hours, as @code{MM:SS}. =*/ SCM ag_scm_time_string_to_number(SCM time_spec) { extern time_t parse_duration(char const * in_pz); char const * pz; time_t time_period; if (! AG_SCM_STRING_P(time_spec)) return SCM_UNDEFINED; pz = scm_i_string_chars(time_spec); time_period = parse_duration(pz); return scm_from_int((int)time_period); }
char *safe_scm_to_stringn (SCM str, size_t *lenp) { char *res; size_t len; if (!scm_is_string (str)) { if(lenp) *lenp = 0; return NULL; } len = scm_i_string_length (str); res = scm_malloc (len + 1); memcpy (res, scm_i_string_chars (str), len); res[len] = '\0'; //unconditionaly null terminate if(lenp) *lenp = len; scm_remember_upto_here_1 (str); return res; }
/*=gfunc string_substitute * * what: multiple global replacements * general_use: * * exparg: source, string to transform * exparg: match, substring or substring list to be replaced * exparg: repl, replacement strings or substrings * * doc: @code{match} and @code{repl} may be either a single string or * a list of strings. Either way, they must have the same structure * and number of elements. For example, to replace all amphersands, * less than and greater than characters, do something like this: * * @example * (string-substitute source * (list "&" "<" ">") * (list "&" "<" ">")) * @end example =*/ SCM ag_scm_string_substitute(SCM str, SCM Match, SCM Repl) { char const * text; ssize_t len; SCM res; if (! AG_SCM_STRING_P(str)) return SCM_UNDEFINED; text = scm_i_string_chars(str); len = (ssize_t)AG_SCM_STRLEN(str); if (AG_SCM_STRING_P(Match)) do_substitution(text, len, Match, Repl, (char **)&text, &len); else do_multi_subs((char **)&text, &len, Match, Repl); res = AG_SCM_STR2SCM(text, (size_t)len); return res; }
/*=gfunc join * * what: join string list with separator * general_use: * exparg: separator, string to insert between entries * exparg: list, list of strings to join,, list * * doc: With the first argument as the separator string, * joins together an a-list of strings into one long string. * The list may contain nested lists, partly because you * cannot always control that. =*/ SCM ag_scm_join(SCM sep, SCM list) { int l_len, sv_l_len; SCM car; SCM alist = list; size_t sep_len; size_t str_len; char * pzRes; char const * pzSep; char * pzScan; if (! AG_SCM_STRING_P(sep)) return SCM_UNDEFINED; sv_l_len = l_len = (int)scm_ilength(list); if (l_len == 0) return AG_SCM_STR02SCM(zNil); pzSep = scm_i_string_chars(sep); sep_len = AG_SCM_STRLEN(sep); str_len = 0; /* * Count up the lengths of all the strings to be joined. */ for (;;) { car = SCM_CAR(list); list = SCM_CDR(list); /* * This routine is listed as getting a list as the second * argument. That means that if someone builds a list and * hands it to us, it magically becomes a nested list. * This unravels that. */ if (! AG_SCM_STRING_P(car)) { if (car != SCM_UNDEFINED) car = ag_scm_join(sep, car); if (! AG_SCM_STRING_P(car)) return SCM_UNDEFINED; } str_len += AG_SCM_STRLEN(car); if (--l_len <= 0) break; str_len += sep_len; } l_len = sv_l_len; pzRes = pzScan = scribble_get((ssize_t)str_len); /* * Now, copy each one into the output */ for (;;) { size_t cpy_len; car = SCM_CAR(alist); alist = SCM_CDR(alist); /* * This unravels nested lists. */ if (! AG_SCM_STRING_P(car)) car = ag_scm_join(sep, car); cpy_len = AG_SCM_STRLEN(car); memcpy(VOIDP(pzScan), scm_i_string_chars(car), cpy_len); pzScan += cpy_len; /* * IF we reach zero, then do not insert a separation and bail out */ if (--l_len <= 0) break; memcpy(VOIDP(pzScan), VOIDP(pzSep), sep_len); pzScan += sep_len; } return AG_SCM_STR2SCM(pzRes, str_len); }