ClassInfo Thing_classFromClassName (const char32 *klas, int *p_formatVersion) { static char32 buffer [1+100]; str32ncpy (buffer, klas ? klas : U"", 100); char32 *space = str32chr (buffer, U' '); if (space) { *space = U'\0'; // strip version number if (p_formatVersion) *p_formatVersion = Melder_atoi (space + 1); } else { if (p_formatVersion) *p_formatVersion = 0; } /* * First try the class names that were registered with Thing_recognizeClassesByName. */ for (int i = 1; i <= theNumberOfReadableClasses; i ++) { ClassInfo classInfo = theReadableClasses [i]; if (str32equ (buffer, classInfo -> className)) { return classInfo; } } /* * Then try the aliases that were registered with Thing_recognizeClassByOtherName. */ for (int i = 1; i <= theNumberOfAliases; i ++) { if (str32equ (buffer, theAliases [i]. otherName)) { ClassInfo classInfo = theAliases [i]. readableClass; return classInfo; } } Melder_throw (U"Class \"", buffer, U"\" not recognized."); }
void structWordList :: v_readBinary (FILE *f) { char32 *current, *p; int kar = 0; our length = bingeti4 (f); if (our length < 0) Melder_throw (U"Wrong length ", our length, U"."); string = Melder_calloc (char32, our length + 1); p = current = string; if (our length > 0) { /* * Read first word. */ for (;;) { if (p - string >= length - 1) break; kar = fgetc (f); if (kar == EOF) Melder_throw (U"Early end of file."); if (kar >= 128) break; *p ++ = kar; } *p ++ = '\n'; /* * Read following words. */ for (;;) { char32 *previous = current; int numberOfSame = kar - 128; current = p; str32ncpy (current, previous, numberOfSame); p += numberOfSame; for (;;) { if (p - string >= length - 1) break; kar = fgetc (f); if (kar == EOF) Melder_throw (U"Early end of file."); if (kar >= 128) break; *p ++ = kar; } *p ++ = '\n'; if (p - string >= length) break; } } *p = '\0'; if (p - string != length) Melder_throw (U"Length in header (", length, U") does not match lenth of string (", (long) (p - string), U")."); }
Strings WordList_to_Strings (WordList me) { try { unsigned char *word = (unsigned char *) my string; // BUG: explain this autoStrings thee = Thing_new (Strings); thy numberOfStrings = WordList_count (me); if (thy numberOfStrings > 0) { thy strings = NUMvector <char32 *> (1, thy numberOfStrings); } for (long i = 1; i <= thy numberOfStrings; i ++) { unsigned char *kar = word; for (; *kar != '\n'; kar ++) { } long length = kar - word; thy strings [i] = Melder_calloc (char32, length + 1); str32ncpy (thy strings [i], Melder_peek8to32 ((const char *) word), length); thy strings [i] [length] = U'\0'; word += length + 1; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Strings."); } }
char32 *str_replace_regexp (const char32 *string, regexp *compiledSearchRE, const char32 *replaceRE, long maximumNumberOfReplaces, long *nmatches) { int buf_nchar = 0; /* # characters in 'buf' */ int gap_copied = 0; int nchar, reverse = 0; int errorType; char32 prev_char = '\0'; const char32 *pos; /* current position in 'string' / start of current match */ const char32 *posp; /* end of previous match */ autostring32 buf; *nmatches = 0; if (string == 0 || compiledSearchRE == 0 || replaceRE == 0) { return 0; } int string_length = str32len (string); //int replace_length = str32len (replaceRE); if (string_length == 0) { maximumNumberOfReplaces = 1; } long i = maximumNumberOfReplaces > 0 ? 0 : - string_length; /* We do not know the size of the replaced string in advance, therefor, we allocate a replace buffer twice the size of the original string. After all replaces have taken place we do a final realloc to the then exactly known size. If during the replace, the size of the buffer happens to be too small (this is signalled by the replaceRE function), we double its size and restart the replace. */ int buf_size = 2 * string_length; buf_size = buf_size < 100 ? 100 : buf_size; buf.resize (buf_size); pos = posp = string; while (ExecRE (compiledSearchRE, 0, pos, 0, reverse, prev_char, '\0', 0, 0, 0) && i++ < maximumNumberOfReplaces) { /* Copy gap between the end of the previous match and the start of the current match. Check buffer overflow. pos == posp ? '\0' : pos[-1], */ pos = compiledSearchRE -> startp[0]; nchar = pos - posp; if (nchar > 0 && ! gap_copied) { if (buf_nchar + nchar + 1 > buf_size) { buf_size *= 2; buf.resize (buf_size); } str32ncpy (buf.peek() + buf_nchar, posp, nchar); buf_nchar += nchar; } gap_copied = 1; /* Do the substitution. We can only check afterwards for buffer overflow. SubstituteRE puts null byte at last replaced position and signals when overflow. */ if ( (SubstituteRE (compiledSearchRE, replaceRE, buf.peek() + buf_nchar, buf_size - buf_nchar, &errorType)) == false) { if (errorType == 1) { // not enough memory buf_size *= 2; buf.resize (buf_size); Melder_clearError (); i--; // retry continue; } Melder_throw (U"Error during substitution."); } // Buffer is not full, get number of characters added; nchar = str32len (buf.peek() + buf_nchar); buf_nchar += nchar; // Update next start position in search string. posp = pos; pos = (char32 *) compiledSearchRE -> endp[0]; if (pos != posp) { prev_char = pos[-1]; } gap_copied = 0; posp = pos; //pb 20080121 (*nmatches) ++; // at end of string? // we need this because .* matches at end of a string if (pos - string == string_length) { break; } } // Copy last part of string to destination string nchar = (string + string_length) - pos; buf_size = buf_nchar + nchar + 1; buf.resize (buf_size); str32ncpy (buf.peek() + buf_nchar, pos, nchar); buf[buf_size - 1] = '\0'; return buf.transfer(); }
char32 *str_replace_literal (const char32 *string, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, long *nmatches) { if (string == 0 || search == 0 || replace == 0) { return NULL; } int len_string = str32len (string); if (len_string == 0) { maximumNumberOfReplaces = 1; } int len_search = str32len (search); if (len_search == 0) { maximumNumberOfReplaces = 1; } /* To allocate memory for 'result' only once, we have to know how many matches will occur. */ const char32 *pos = string; //current position / start of current match *nmatches = 0; if (maximumNumberOfReplaces <= 0) { maximumNumberOfReplaces = LONG_MAX; } if (len_search == 0) { /* Search is empty string... */ if (len_string == 0) { *nmatches = 1; /* ...only matches empty string */ } } else { if (len_string != 0) { /* Because empty string always matches */ while ( (pos = str32str (pos, search)) && *nmatches < maximumNumberOfReplaces) { pos += len_search; (*nmatches) ++; } } } int64 len_replace = str32len (replace); int64 len_result = len_string + *nmatches * (len_replace - len_search); char32 *result = Melder_malloc (char32, (len_result + 1) * (int64) sizeof (char32)); result[len_result] = '\0'; const char32 *posp = pos = string; int nchar = 0, result_nchar = 0; for (long i = 1; i <= *nmatches; i++) { pos = str32str (pos, search); /* Copy gap between end of previous match and start of current. */ nchar = (pos - posp); if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); result_nchar += nchar; } /* Insert the replace string in result. */ str32ncpy (result + result_nchar, replace, len_replace); result_nchar += len_replace; /* Next search starts after the match. */ pos += len_search; posp = pos; } /* Copy gap between end of match and end of string. */ pos = string + len_string; nchar = pos - posp; if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); } return result; }