static void NativeMenuItem_setText (GuiObject me) { int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers; static MelderString title { 0 }; if (acc == 0) { MelderString_copy (& title, _GuiWin_expandAmpersands (my name)); } else { static const char32 *keyStrings [256] = { 0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown", U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0, U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/", U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?", U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O", U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_", U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o", U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\", U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???"; MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t", modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr, modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr, modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString); } ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string)); }
char32 * Thing_messageName (Thing me) { static MelderString buffers [19] { { 0 } }; static int ibuffer = 0; if (++ ibuffer == 19) ibuffer = 0; if (my name) { MelderString_copy (& buffers [ibuffer], my classInfo -> className, U" \"", my name, U"\""); } else { MelderString_copy (& buffers [ibuffer], my classInfo -> className); } return buffers [ibuffer]. string; }
static void NativeMenuItem_setText (GuiObject me) { int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers; #if win static MelderString title { 0 }; if (acc == 0) { MelderString_copy (& title, _GuiWin_expandAmpersands (my name)); } else { static const char32 *keyStrings [256] = { 0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown", U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0, U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/", U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?", U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O", U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_", U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o", U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\", U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???"; MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t", modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr, modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr, modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString); } ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string)); #elif mac static int theGlyphs [1+31] = { 0, kMenuLeftArrowDashedGlyph, kMenuRightArrowDashedGlyph, kMenuUpArrowDashedGlyph, kMenuDownwardArrowDashedGlyph, 0, kMenuDeleteRightGlyph, 0, kMenuDeleteLeftGlyph, kMenuTabRightGlyph, 0, 0, 0, kMenuReturnGlyph, kMenuPageUpGlyph, kMenuPageDownGlyph, kMenuEscapeGlyph, kMenuF1Glyph, kMenuF2Glyph, kMenuF3Glyph, kMenuF4Glyph, kMenuF5Glyph, kMenuF6Glyph, kMenuF7Glyph, kMenuF8Glyph, kMenuF9Glyph, kMenuF10Glyph, kMenuF11Glyph, kMenuF12Glyph, 0, 0, 0 }; SetMenuItemTextWithCFString (my nat.entry.handle, my nat.entry.item, (CFStringRef) Melder_peek32toCfstring (my name)); if (acc > 32) { SetItemCmd (my nat.entry.handle, my nat.entry.item, acc); } else { Melder_assert (acc > 0 && acc < 32); SetItemCmd (my nat.entry.handle, my nat.entry.item, ' '); /* Funny that this should be needed. */ SetMenuItemKeyGlyph (my nat.entry.handle, my nat.entry.item, theGlyphs [acc]); } SetMenuItemModifiers (my nat.entry.handle, my nat.entry.item, ( modifiers & _motif_OPTION_MASK ? kMenuOptionModifier : 0 ) + ( modifiers & _motif_SHIFT_MASK ? kMenuShiftModifier : 0 ) + ( modifiers & _motif_COMMAND_MASK ? 0 : kMenuNoCommandModifier )); #endif }
void TableOfReal_writeToHeaderlessSpreadsheetFile (TableOfReal me, MelderFile file) { try { autoMelderString buffer; MelderString_copy (& buffer, L"rowLabel"); for (long icol = 1; icol <= my numberOfColumns; icol ++) { MelderString_appendCharacter (& buffer, '\t'); wchar_t *s = my columnLabels [icol]; MelderString_append (& buffer, s != NULL && s [0] != '\0' ? s : L"?"); } MelderString_appendCharacter (& buffer, '\n'); for (long irow = 1; irow <= my numberOfRows; irow ++) { wchar_t *s = my rowLabels [irow]; MelderString_append (& buffer, s != NULL && s [0] != '\0' ? s : L"?"); for (long icol = 1; icol <= my numberOfColumns; icol ++) { MelderString_appendCharacter (& buffer, '\t'); double x = my data [irow] [icol]; MelderString_append (& buffer, Melder_double (x)); } MelderString_appendCharacter (& buffer, '\n'); } MelderFile_writeText (file, buffer.string, Melder_getOutputEncoding ()); } catch (MelderError) { Melder_throw (me, ": not saved to tab-separated file."); } }
void structOTMultiEditor :: v_draw () { OTMulti grammar = (OTMulti) data; static MelderString buffer { 0 }; double rowHeight = 0.25, tableauHeight = 2 * rowHeight; Graphics_clearWs (g); HyperPage_listItem (this, U"\t\t %%ranking value\t %disharmony\t %plasticity"); for (long icons = 1; icons <= grammar -> numberOfConstraints; icons ++) { OTConstraint constraint = & grammar -> constraints [grammar -> index [icons]]; MelderString_copy (& buffer, U"\t", ( icons == selectedConstraint ? U"♠︎ " : U" " ), U"@@", icons, U"|", constraint -> name, U"@\t ", Melder_fixed (constraint -> ranking, 3), U"\t ", Melder_fixed (constraint -> disharmony, 3), U"\t ", Melder_fixed (constraint -> plasticity, 6) ); HyperPage_listItem (this, buffer.string); } Graphics_setAtSignIsLink (g, FALSE); drawTableau_grammar = grammar; for (long icand = 1; icand <= grammar -> numberOfCandidates; icand ++) { if (OTMulti_candidateMatches (grammar, icand, form1, form2)) { tableauHeight += rowHeight; } } drawTableau_form1 = form1; drawTableau_form2 = form2; drawTableau_constraintsAreDrawnVertically = d_constraintsAreDrawnVertically; HyperPage_picture (this, 20, tableauHeight, drawTableau); Graphics_setAtSignIsLink (g, TRUE); }
void Melder_system (const char32 *command) { if (! command) command = U""; #if defined (macintosh) || defined (UNIX) if (system (Melder_peek32to8 (command)) != 0) Melder_throw (U"System command failed."); #elif defined (_WIN32) STARTUPINFO siStartInfo; PROCESS_INFORMATION piProcInfo; char32 *comspec = Melder_getenv (U"COMSPEC"); // e.g. "C:\WINDOWS\COMMAND.COM" or "C:\WINNT\windows32\cmd.exe" if (! comspec) { comspec = Melder_getenv (U"ComSpec"); } autoMelderString buffer; if (comspec) { MelderString_copy (& buffer, comspec); } else { OSVERSIONINFOEX osVersionInfo; memset (& osVersionInfo, 0, sizeof (OSVERSIONINFOEX)); osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) { osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) Melder_throw (U"System command cannot find system version."); } switch (osVersionInfo. dwPlatformId) { case VER_PLATFORM_WIN32_NT: { MelderString_copy (& buffer, U"cmd.exe"); } break; case VER_PLATFORM_WIN32_WINDOWS: { MelderString_copy (& buffer, U"command.com"); } break; default: { MelderString_copy (& buffer, U"command.com"); } } } MelderString_append (& buffer, U" /c ", command); memset (& siStartInfo, 0, sizeof (siStartInfo)); siStartInfo. cb = sizeof (siStartInfo); if (! CreateProcess (nullptr, Melder_peek32toW (buffer.string), nullptr, nullptr, true, CREATE_NO_WINDOW, nullptr, nullptr, & siStartInfo, & piProcInfo)) Melder_throw (U"Cannot create subprocess."); WaitForSingleObject (piProcInfo. hProcess, -1); CloseHandle (piProcInfo. hProcess); CloseHandle (piProcInfo. hThread); #endif }
autostring32 FFNet_createNameFromTopology (FFNet me) { autoMelderString name; MelderString_copy (&name, my nUnitsInLayer[0]); for (long i = 1; i <= my nLayers; i++) { MelderString_appendCharacter (&name, U'-'); MelderString_append (&name, my nUnitsInLayer[i]); } autostring32 naam = Melder_dup (name.string); return naam.transfer(); }
void Melder_system (const wchar_t *command) { #if defined (macintosh) || defined (UNIX) if (system (Melder_peekWcsToUtf8 (command)) != 0) Melder_throw ("System command failed."); #elif defined (_WIN32) STARTUPINFO siStartInfo; PROCESS_INFORMATION piProcInfo; wchar_t *comspec = Melder_getenv (L"COMSPEC"); // e.g. "C:\WINDOWS\COMMAND.COM" or "C:\WINNT\windows32\cmd.exe" if (comspec == NULL) { comspec = Melder_getenv (L"ComSpec"); } MelderString buffer = { 0 }; if (comspec != NULL) { MelderString_copy (& buffer, comspec); } else { OSVERSIONINFOEX osVersionInfo; memset (& osVersionInfo, 0, sizeof (OSVERSIONINFOEX)); osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) { osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) Melder_throw ("System command cannot find system version."); } switch (osVersionInfo. dwPlatformId) { case VER_PLATFORM_WIN32_NT: { MelderString_copy (& buffer, L"cmd.exe"); } break; case VER_PLATFORM_WIN32_WINDOWS: { MelderString_copy (& buffer, L"command.com"); } break; default: { MelderString_copy (& buffer, L"command.com"); } } } MelderString_append (& buffer, L" /c ", command); memset (& siStartInfo, 0, sizeof (siStartInfo)); siStartInfo. cb = sizeof (siStartInfo); if (! CreateProcess (NULL, buffer.string, NULL, NULL, TRUE, 0, NULL, NULL, & siStartInfo, & piProcInfo)) Melder_throw ("Cannot create subprocess."); WaitForSingleObject (piProcInfo. hProcess, -1); CloseHandle (piProcInfo. hProcess); CloseHandle (piProcInfo. hThread); #endif }
const char32 * Melder_pad (const char32 *string, int64 width) { if (++ iPadBuffer == NUMBER_OF_BUFFERS) iPadBuffer = 0; int64 length = str32len (string); int64 tooShort = width - length; if (tooShort <= 0) return string; MelderString_copy (& thePadBuffers [iPadBuffer], string); for (int64 i = 0; i < tooShort; i ++) MelderString_appendCharacter (& thePadBuffers [iPadBuffer], U' '); return thePadBuffers [iPadBuffer]. string; }
static void NativeMenuItem_setText (GuiObject me) { int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers; #if win static MelderString title = { 0 }; if (acc == 0) { MelderString_copy (& title, _GuiWin_expandAmpersands (my name)); } else { static const wchar_t *keyStrings [256] = { 0, L"<-", L"->", L"Up", L"Down", L"PAUSE", L"Del", L"Ins", L"Backspace", L"Tab", L"LineFeed", L"Home", L"End", L"Enter", L"PageUp", L"PageDown", L"Esc", L"F1", L"F2", L"F3", L"F4", L"F5", L"F6", L"F7", L"F8", L"F9", L"F10", L"F11", L"F12", 0, 0, 0, L"Space", L"!", L"\"", L"#", L"$", L"%", L"&", L"\'", L"(", L")", L"*", L"+", L",", L"-", L".", L"/", L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9", L":", L";", L"<", L"=", L">", L"?", L"@", L"A", L"B", L"C", L"D", L"E", L"F", L"G", L"H", L"I", L"J", L"K", L"L", L"M", L"N", L"O", L"P", L"Q", L"R", L"S", L"T", L"U", L"V", L"W", L"X", L"Y", L"Z", L"[", L"\\", L"]", L"^", L"_", L"`", L"a", L"b", L"c", L"d", L"e", L"f", L"g", L"h", L"i", L"j", L"k", L"l", L"m", L"n", L"o", L"p", L"q", L"r", L"s", L"t", L"u", L"v", L"w", L"x", L"y", L"z", L"{", L"|", L"}", L"~", L"Del", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"[", L"]", L",", L"?", L".", L"\\", L";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"-", L"`", L"=", L"\'", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const wchar_t *keyString = keyStrings [acc] ? keyStrings [acc] : L"???"; MelderString_empty (& title); MelderString_append (& title, _GuiWin_expandAmpersands (my name), L"\t", modifiers & _motif_COMMAND_MASK ? L"Ctrl-" : NULL, modifiers & _motif_OPTION_MASK ? L"Alt-" : NULL, modifiers & _motif_SHIFT_MASK ? L"Shift-" : NULL, keyString); } ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, title.string); #elif mac static int theGlyphs [1+31] = { 0, kMenuLeftArrowDashedGlyph, kMenuRightArrowDashedGlyph, kMenuUpArrowDashedGlyph, kMenuDownwardArrowDashedGlyph, 0, kMenuDeleteRightGlyph, 0, kMenuDeleteLeftGlyph, kMenuTabRightGlyph, 0, 0, 0, kMenuReturnGlyph, kMenuPageUpGlyph, kMenuPageDownGlyph, kMenuEscapeGlyph, kMenuF1Glyph, kMenuF2Glyph, kMenuF3Glyph, kMenuF4Glyph, kMenuF5Glyph, kMenuF6Glyph, kMenuF7Glyph, kMenuF8Glyph, kMenuF9Glyph, kMenuF10Glyph, kMenuF11Glyph, kMenuF12Glyph, 0, 0, 0 }; SetMenuItemTextWithCFString (my nat.entry.handle, my nat.entry.item, (CFStringRef) Melder_peekWcsToCfstring (my name)); if (acc > 32) { SetItemCmd (my nat.entry.handle, my nat.entry.item, acc); } else { Melder_assert (acc > 0 && acc < 32); SetItemCmd (my nat.entry.handle, my nat.entry.item, ' '); /* Funny that this should be needed. */ SetMenuItemKeyGlyph (my nat.entry.handle, my nat.entry.item, theGlyphs [acc]); } SetMenuItemModifiers (my nat.entry.handle, my nat.entry.item, ( modifiers & _motif_OPTION_MASK ? kMenuOptionModifier : 0 ) + ( modifiers & _motif_SHIFT_MASK ? kMenuShiftModifier : 0 ) + ( modifiers & _motif_COMMAND_MASK ? 0 : kMenuNoCommandModifier )); #endif }
void structTextEditor :: v_nameChanged () { if (v_fileBased ()) { bool dirtinessAlreadyShown = GuiWindow_setDirty (our d_windowForm, our dirty); static MelderString windowTitle { 0 }; if (our name [0] == U'\0') { MelderString_copy (& windowTitle, U"(untitled"); if (dirty && ! dirtinessAlreadyShown) MelderString_append (& windowTitle, U", modified"); MelderString_append (& windowTitle, U")"); } else { MelderString_copy (& windowTitle, U"File ", MelderFile_messageName (& our file)); if (dirty && ! dirtinessAlreadyShown) MelderString_append (& windowTitle, U" (modified)"); } GuiShell_setTitle (our d_windowForm, windowTitle.string); //MelderString_copy (& windowTitle, our dirty && ! dirtinessAlreadyShown ? U"*" : U"", our name [0] == U'\0' ? U"(untitled)" : MelderFile_name (& our file)); } else { TextEditor_Parent :: v_nameChanged (); } }
void structScriptEditor :: v_nameChanged () { bool dirtinessAlreadyShown = d_windowForm -> f_setDirty (dirty); static MelderString buffer = { 0 }; MelderString_copy (& buffer, name [0] ? L"Script" : L"untitled script"); if (editorClass) MelderString_append (& buffer, L" [", environmentName, L"]"); if (name [0]) MelderString_append (& buffer, L" ", MelderFile_messageName (& file)); if (dirty && ! dirtinessAlreadyShown) MelderString_append (& buffer, L" (modified)"); d_windowForm -> f_setTitle (buffer.string); }
void structScriptEditor :: v_nameChanged () { bool dirtinessAlreadyShown = GuiWindow_setDirty (d_windowForm, dirty); static MelderString buffer { 0 }; MelderString_copy (& buffer, name [0] ? U"Script" : U"untitled script"); if (editorClass) MelderString_append (& buffer, U" [", environmentName, U"]"); if (name [0]) MelderString_append (& buffer, U" ", MelderFile_messageName (& file)); if (dirty && ! dirtinessAlreadyShown) MelderString_append (& buffer, U" (modified)"); GuiShell_setTitle (d_windowForm, buffer.string); }
static void menu_cb_writeOneToHtmlFile (Manual me, EDITOR_ARGS_FORM) { EDITOR_FORM_WRITE (U"Save as HTML file", nullptr) ManPages manPages = (ManPages) my data; autoMelderString buffer; MelderString_copy (& buffer, manPages -> pages.at [my path] -> title); char32 *p = buffer.string; while (*p) { if (! isalnum ((int) *p) && *p != U'_') *p = U'_'; p ++; } MelderString_append (& buffer, U".html"); Melder_sprint (defaultName,300, buffer.string); EDITOR_DO_WRITE ManPages_writeOneToHtmlFile ((ManPages) my data, my path, file); EDITOR_END }
const char32 * Melder_padOrTruncate (const char32 *string, int64 width) { if (++ iPadBuffer == NUMBER_OF_BUFFERS) iPadBuffer = 0; int64 length = str32len (string); int64 tooLong = length - width; if (tooLong == 0) return string; if (tooLong < 0) { int64 tooShort = - tooLong; MelderString_copy (& thePadBuffers [iPadBuffer], string); for (int64 i = 0; i < tooShort; i ++) MelderString_appendCharacter (& thePadBuffers [iPadBuffer], U' '); } else { MelderString_ncopy (& thePadBuffers [iPadBuffer], string, width); } return thePadBuffers [iPadBuffer]. string; }
static double searchToken (ManPages me, long ipage, wchar_t *token) { double goodness = 0.0; ManPage page = (ManPage) my pages -> item [ipage]; struct structManPage_Paragraph *par = & page -> paragraphs [0]; if (! token [0]) return 1.0; /* * Try to find a match in the title, case insensitively. */ static MelderString buffer = { 0 }; MelderString_copy (& buffer, page -> title); for (wchar_t *p = & buffer.string [0]; *p != '\0'; p ++) *p = tolower (*p); if (wcsstr (buffer.string, token)) { goodness += 300.0; /* Lots of points for a match in the title! */ if (wcsequ (buffer.string, token)) goodness += 10000.0; /* Even more points for an exact match! */ } /* * Try to find a match in the paragraphs, case-insensitively. */ while (par -> type) { if (par -> text) { wchar_t *ptoken; MelderString_copy (& buffer, par -> text); for (wchar_t *p = & buffer.string [0]; *p != '\0'; p ++) *p = tolower (*p); ptoken = wcsstr (buffer.string, token); if (ptoken) { goodness += 10.0; /* Ten points for every paragraph with a match! */ if (wcsstr (ptoken + wcslen (token), token)) { goodness += 1.0; /* One point for every second occurrence in a paragraph! */ } } } par ++; } return goodness; }
static double searchToken (ManPages me, long ipage, char32 *token) { double goodness = 0.0; ManPage page = my pages.at [ipage]; struct structManPage_Paragraph *par = & page -> paragraphs [0]; if (! token [0]) return 1.0; /* * Try to find a match in the title, case insensitively. */ static MelderString buffer { 0 }; MelderString_copy (& buffer, page -> title); for (char32 *p = & buffer.string [0]; *p != U'\0'; p ++) *p = towlower ((int) *p); if (str32str (buffer.string, token)) { goodness += 300.0; // lots of points for a match in the title! if (str32equ (buffer.string, token)) goodness += 10000.0; // even more points for an exact match! } /* * Try to find a match in the paragraphs, case-insensitively. */ while (par -> type) { if (par -> text) { char32 *ptoken; MelderString_copy (& buffer, par -> text); for (char32 *p = & buffer.string [0]; *p != '\0'; p ++) *p = towlower ((int) *p); ptoken = str32str (buffer.string, token); if (ptoken) { goodness += 10.0; // ten points for every paragraph with a match! if (str32str (ptoken + str32len (token), token)) { goodness += 1.0; // one point for every second occurrence in a paragraph! } } } par ++; } return goodness; }
static void EEG_setChannelNames_selected (EEG me, const char32 *precursor, long *channelNumbers, long numberOfChannels) { autoMelderString name; const char32 *zero = U"0"; for (long i = 1; i <= numberOfChannels; i++) { MelderString_copy (&name, precursor); if (my numberOfChannels > 100) { if (i < 10) { MelderString_append (&name, zero); } if (i < 100) { MelderString_append (&name, zero); } } else if (i < 10) { MelderString_append (&name, zero); } MelderString_append (&name, i); EEG_setChannelName (me, channelNumbers[i], name.string); } }
static void search (Manual me, const char32 *query) { ManPages manPages = (ManPages) my data; long numberOfPages = manPages -> pages.size; static MelderString searchText { 0 }; MelderString_copy (& searchText, query); for (char32 *p = & searchText.string [0]; *p != U'\0'; p ++) { if (*p == U'\n') *p = U' '; *p = towlower ((int) *p); } if (! goodnessOfMatch) goodnessOfMatch = NUMvector <double> (1, numberOfPages); for (long ipage = 1; ipage <= numberOfPages; ipage ++) { char32 *token = searchText.string; goodnessOfMatch [ipage] = 1.0; for (;;) { char32 *space = str32chr (token, U' '); if (space) *space = U'\0'; goodnessOfMatch [ipage] *= searchToken (manPages, ipage, token); if (! space) break; *space = U' '; // restore token = space + 1; } } /* * Find the 20 best matches. */ my numberOfMatches = 0; for (long imatch = 1; imatch <= 20; imatch ++) { long imax = 0; double max = 0.0; for (long ipage = 1; ipage <= numberOfPages; ipage ++) { if (goodnessOfMatch [ipage] > max) { max = goodnessOfMatch [ipage]; imax = ipage; } } if (! imax) break; my matches [++ my numberOfMatches] = imax; goodnessOfMatch [imax] = 0.0; // skip next time } HyperPage_goToPage_i (me, SEARCH_PAGE); }
void FileInMemorySet_showAsCode (FileInMemorySet me, const char32 *name, long numberOfBytesPerLine) { autoMelderString one_fim; MelderInfo_writeLine (U"#include \"Collection.h\""); MelderInfo_writeLine (U"#include \"FileInMemory.h\""); MelderInfo_writeLine (U"#include \"melder.h\"\n"); MelderInfo_writeLine (U"autoFilesInMemory create_", name, U" () {"); MelderInfo_writeLine (U"\ttry {"); MelderInfo_writeLine (U"\t\tautoFilesInMemory me = FilesInMemory_create ();"); for (long ifile = 1; ifile <= my size; ifile ++) { FileInMemory fim = my at [ifile]; MelderString_copy (& one_fim, name, ifile); FileInMemory_showAsCode (fim, one_fim.string, numberOfBytesPerLine); MelderInfo_writeLine (U"\t\tCollection_addItem_move (me.peek(), ", one_fim.string, U".move());\n"); } MelderInfo_writeLine (U"\t\treturn me;"); MelderInfo_writeLine (U"\t} catch (MelderError) {"); MelderInfo_writeLine (U"\t\tMelder_throw (U\"FileInMemorySet not created.\");"); MelderInfo_writeLine (U"\t}"); MelderInfo_writeLine (U"}\n\n"); }
autoMovie Movie_openFromSoundFile (MelderFile file) { try { autoMovie me = Thing_new (Movie); autoSound sound = Sound_readFromSoundFile (file); autoMelderString fileNameHead; MelderString_copy (& fileNameHead, Melder_fileToPath (file)); char32 *extensionLocation = str32rchr (fileNameHead.string, U'.'); if (! extensionLocation) extensionLocation = & fileNameHead.string [fileNameHead.length]; *extensionLocation = U'\0'; fileNameHead.length = extensionLocation - fileNameHead.string; autoStrings strings = Strings_createAsFileList (Melder_cat (fileNameHead.string, U"*.png")); struct structMelderDir folder; MelderFile_getParentDir (file, & folder); Movie_init (me.peek(), sound.transfer(), Melder_dirToPath (& folder), strings.transfer()); return me; } catch (MelderError) { Melder_throw (U"Movie object not read from file ", file, U"."); } }
int Praat_tests (int itest, char32 *arg1, char32 *arg2, char32 *arg3, char32 *arg4) { int64 n = Melder_atoi (arg1); double t = 0.0; (void) arg1; (void) arg2; (void) arg3; (void) arg4; Melder_clearInfo (); Melder_stopwatch (); switch (itest) { case kPraatTests_TIME_RANDOM_FRACTION: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomFraction (); t = Melder_stopwatch (); } break; case kPraatTests_TIME_RANDOM_GAUSS: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomGauss (0.0, 1.0); t = Melder_stopwatch (); } break; case kPraatTests_TIME_SORT: { long m = Melder_atoi (arg2); long *array = NUMvector <long> (1, m); for (int64 i = 1; i <= m; i ++) array [i] = NUMrandomInteger (1, 100); Melder_stopwatch (); for (int64 i = 1; i <= n; i ++) NUMsort_l (m, array); t = Melder_stopwatch (); NUMvector_free (array, 1); } break; case kPraatTests_TIME_INTEGER: { int64 sum = 0; for (int64 i = 1; i <= n; i ++) sum += i * (i - 1) * (i - 2); t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT: { double sum = 0.0, fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += fi * (fi - 1.0) * (fi - 2.0); t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_BUILTIN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32) fi; t = Melder_stopwatch (); // 2.59 // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_EXTERN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32) ((int32) (fi - 2147483648.0) + 2147483647L + 1); t = Melder_stopwatch (); // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_BUILTIN: { double sum = 0.0; uint32 nu = (uint32) n; for (uint32 iu = 1; iu <= nu; iu ++) sum += (double) iu; t = Melder_stopwatch (); // 1.35 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_EXTERN: { double sum = 0.0; uint32 nu = (uint32) n; for (uint32 iu = 1; iu <= nu; iu ++) sum += (double) (int32) (iu - 2147483647L - 1) + 2147483648.0; t = Melder_stopwatch (); // 0.96 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_STRING_MELDER_32: { autoMelderString string; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { MelderString_copy (& string, word); for (int j = 1; j <= 30; j ++) MelderString_append (& string, word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_MELDER_32_ALLOC: { char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { autoMelderString string; MelderString_copy (& string, word); for (int j = 1; j <= 30; j ++) MelderString_append (& string, word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_S: { std::string s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_C: { std::basic_string<char> s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WS: { std::wstring s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WC: { std::basic_string<wchar_t> s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_32: { std::basic_string<char32_t> s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_U32STRING: { std::u32string s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRCPY: { char buffer [100]; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { strcpy (buffer, word); for (int j = 1; j <= 30; j ++) strcpy (buffer + strlen (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (Melder_peek8to32 (buffer)); } break; case kPraatTests_TIME_WCSCPY: { wchar_t buffer [100]; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { wcscpy (buffer, word); for (int j = 1; j <= 30; j ++) wcscpy (buffer + wcslen (buffer), word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STR32CPY: { char32 buffer [100]; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { str32cpy (buffer, word); for (int j = 1; j <= 30; j ++) str32cpy (buffer + str32len (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (buffer); } break; case kPraatTests_TIME_GRAPHICS_TEXT_TOP: { autoPraatPicture picture; for (int64 i = 1; i <= n; i ++) { Graphics_textTop (GRAPHICS, false, U"hello world"); } t = Melder_stopwatch (); } break; case kPraatTests_THING_AUTO: { int numberOfThingsBefore = theTotalNumberOfThings; { Melder_casual (U"1\n"); autoDaata data = Thing_new (Daata); Thing_setName (data.get(), U"hello"); Melder_casual (U"2\n"); testData (data.get()); testAutoData (data.move()); autoDaata data18 = Thing_new (Daata); testAutoData (data18.move()); fprintf (stderr, "3\n"); autoDaata data2 = newAutoData (); fprintf (stderr, "4\n"); autoDaata data3 = newAutoData (); fprintf (stderr, "5\n"); //data2 = data; // disabled l-value copy assignment from same class fprintf (stderr, "6\n"); autoOrdered ordered = Thing_new (Ordered); fprintf (stderr, "7\n"); //data = ordered; // disabled l-value copy assignment from subclass data = ordered.move(); //ordered = data; // disabled l-value copy assignment from superclass //ordered = data.move(); // assignment from superclass to subclass is rightfully refused by compiler fprintf (stderr, "8\n"); data2 = newAutoData (); fprintf (stderr, "8a\n"); autoDaata data5 = newAutoData (); fprintf (stderr, "8b\n"); data2 = data5.move(); fprintf (stderr, "9\n"); //ordered = data; // rightfully refused by compiler fprintf (stderr, "10\n"); //autoOrdered ordered2 = Thing_new (Daata); // rightfully refused by compiler fprintf (stderr, "11\n"); autoDaata data4 = Thing_new (Ordered); // constructor fprintf (stderr, "12\n"); //autoDaata data6 = data4; // disabled l-value copy constructor from same class fprintf (stderr, "13\n"); autoDaata data7 = data4.move(); fprintf (stderr, "14\n"); autoOrdered ordered3 = Thing_new (Ordered); autoDaata data8 = ordered3.move(); fprintf (stderr, "15\n"); //autoDaata data9 = ordered; // disabled l-value copy constructor from subclass fprintf (stderr, "16\n"); autoDaata data10 = data7.move(); fprintf (stderr, "17\n"); autoDaata data11 = Thing_new (Daata); // constructor, move assignment, null destructor fprintf (stderr, "18\n"); data11 = Thing_new (Ordered); fprintf (stderr, "19\n"); testAutoDataRef (data11); fprintf (stderr, "20\n"); //data11 = nullptr; // disabled implicit assignment of pointer to autopointer fprintf (stderr, "21\n"); } int numberOfThingsAfter = theTotalNumberOfThings; fprintf (stderr, "Number of things: before %d, after %d\n", numberOfThingsBefore, numberOfThingsAfter); #if 1 MelderCallback<void,structDaata>::FunctionType f; typedef void (*DataFunc) (Daata); typedef void (*OrderedFunc) (Ordered); DataFunc dataFun; OrderedFunc orderedFun; MelderCallback<void,structDaata> dataFun2 (dataFun); MelderCallback<void,structOrdered> orderedFun2 (orderedFun); MelderCallback<void,structDaata> dataFun3 (orderedFun); //MelderCallback<void,structOrdered> orderedFun3 (dataFun); // rightfully refused by compiler autoDaata data = Thing_new (Daata); dataFun3 (data.get()); #endif } break; } MelderInfo_writeLine (Melder_single (t / n * 1e9), U" nanoseconds"); MelderInfo_close (); return 1; }
void Melder_progress (double progress, Melder_19_ARGS) { MelderString_copy (& theProgressBuffer, Melder_19_ARGS_CALL); _Melder_progress (progress, theProgressBuffer.string); }
void * Melder_monitor (double progress, Melder_19_ARGS) { MelderString_copy (& theProgressBuffer, Melder_19_ARGS_CALL); return _Melder_monitor (progress, theProgressBuffer.string); }
void Melder_warning (Melder_19_ARGS) { if (theWarningDepth < 0) return; MelderString_copy (& theWarningBuffer, Melder_19_ARGS_CALL); theMelder. warning (theWarningBuffer.string); }
void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double globalMaximum) { Sound sound = my d_sound.data; LongSound longSound = my d_longSound.data; Melder_assert (!! sound != !! longSound); int nchan = sound ? sound -> ny : longSound -> numberOfChannels; bool cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow; Graphics_setColour (my d_graphics, Graphics_BLACK); bool fits; try { fits = sound ? true : LongSound_haveWindow (longSound, my d_startWindow, my d_endWindow); } catch (MelderError) { bool outOfMemory = !! str32str (Melder_getError (), U"memory"); if (Melder_debug == 9) Melder_flushError (); else Melder_clearError (); Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, outOfMemory ? U"(out of memory)" : U"(cannot read sound file)"); return; } if (! fits) { Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, U"(window too large; zoom in to see the data)"); return; } long first, last; if (Sampled_getWindowSamples (sound ? (Sampled) sound : (Sampled) longSound, my d_startWindow, my d_endWindow, & first, & last) <= 1) { Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_setTextAlignment (my d_graphics, Graphics_CENTRE, Graphics_HALF); Graphics_text (my d_graphics, 0.5, 0.5, U"(zoom out to see the data)"); return; } const int numberOfVisibleChannels = nchan > 8 ? 8 : nchan; const int firstVisibleChannel = my d_sound.channelOffset + 1; int lastVisibleChannel = my d_sound.channelOffset + numberOfVisibleChannels; if (lastVisibleChannel > nchan) lastVisibleChannel = nchan; double maximumExtent = 0.0, visibleMinimum = 0.0, visibleMaximum = 0.0; if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) { if (longSound) LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, firstVisibleChannel, & visibleMinimum, & visibleMaximum); else Matrix_getWindowExtrema (sound, first, last, firstVisibleChannel, firstVisibleChannel, & visibleMinimum, & visibleMaximum); for (int ichan = firstVisibleChannel + 1; ichan <= lastVisibleChannel; ichan ++) { double visibleChannelMinimum, visibleChannelMaximum; if (longSound) LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & visibleChannelMinimum, & visibleChannelMaximum); else Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & visibleChannelMinimum, & visibleChannelMaximum); if (visibleChannelMinimum < visibleMinimum) visibleMinimum = visibleChannelMinimum; if (visibleChannelMaximum > visibleMaximum) visibleMaximum = visibleChannelMaximum; } maximumExtent = visibleMaximum - visibleMinimum; } for (int ichan = firstVisibleChannel; ichan <= lastVisibleChannel; ichan ++) { double cursorFunctionValue = longSound ? 0.0 : Vector_getValueAtX (sound, 0.5 * (my d_startSelection + my d_endSelection), ichan, 70); /* * BUG: this will only work for mono or stereo, until Graphics_function16 handles quadro. */ double ymin = (double) (numberOfVisibleChannels - ichan + my d_sound.channelOffset) / numberOfVisibleChannels; double ymax = (double) (numberOfVisibleChannels + 1 - ichan + my d_sound.channelOffset) / numberOfVisibleChannels; Graphics_Viewport vp = Graphics_insetViewport (my d_graphics, 0, 1, ymin, ymax); bool horizontal = false; double minimum = sound ? globalMinimum : -1.0, maximum = sound ? globalMaximum : 1.0; if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) { if (nchan > 2) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } if (maximumExtent > 0.0) { double middle = 0.5 * (minimum + maximum); minimum = middle - 0.5 * maximumExtent; maximum = middle + 0.5 * maximumExtent; } } else { minimum = visibleMinimum; maximum = visibleMaximum; } } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) { if (longSound) { LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum); } else { Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum); } double channelExtent = my p_sound_scaling_height; double middle = 0.5 * (minimum + maximum); minimum = middle - 0.5 * channelExtent; maximum = middle + 0.5 * channelExtent; } else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_RANGE) { minimum = my p_sound_scaling_minimum; maximum = my p_sound_scaling_maximum; } if (minimum == maximum) { horizontal = true; minimum -= 1.0; maximum += 1.0;} Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum); if (horizontal) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); double mid = 0.5 * (minimum + maximum); Graphics_text (my d_graphics, my d_startWindow, mid, Melder_float (Melder_half (mid))); } else { if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - minimum) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, minimum, Melder_float (Melder_half (minimum))); } if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics, maximum - cursorFunctionValue) > 5.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_TOP); Graphics_text (my d_graphics, my d_startWindow, maximum, Melder_float (Melder_half (maximum))); } } if (minimum < 0 && maximum > 0 && ! horizontal) { Graphics_setWindow (my d_graphics, 0, 1, minimum, maximum); if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || fabs (Graphics_dyWCtoMM (my d_graphics, cursorFunctionValue - 0.0)) > 3.0) { Graphics_setTextAlignment (my d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (my d_graphics, 0, 0, U"0"); } Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_setLineType (my d_graphics, Graphics_DOTTED); Graphics_line (my d_graphics, 0, 0, 1, 0); Graphics_setLineType (my d_graphics, Graphics_DRAWN); } /* * Garnish the drawing area of each channel. */ Graphics_setWindow (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_CYAN); Graphics_innerRectangle (my d_graphics, 0, 1, 0, 1); Graphics_setColour (my d_graphics, Graphics_BLACK); if (nchan > 1) { Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_HALF); const char32 *channelName = my v_getChannelName (ichan); static MelderString channelLabel; MelderString_copy (& channelLabel, ( channelName ? U"ch" : U"Channel " ), ichan); if (channelName) MelderString_append (& channelLabel, U": ", channelName); if (ichan > 8 && ichan - my d_sound.channelOffset == 1) { MelderString_append (& channelLabel, U" " UNITEXT_UPWARDS_ARROW); } else if (ichan >= 8 && ichan - my d_sound.channelOffset == 8 && ichan < nchan) { MelderString_append (& channelLabel, U" " UNITEXT_DOWNWARDS_ARROW); } Graphics_text (my d_graphics, 1, 0.5, channelLabel.string); } /* * Draw a very thin separator line underneath. */ if (ichan < nchan) { /*Graphics_setColour (d_graphics, Graphics_BLACK);*/ Graphics_line (my d_graphics, 0, 0, 1, 0); } /* * Draw the samples. */ /*if (ichan == 1) FunctionEditor_SoundAnalysis_drawPulses (this);*/ if (sound) { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum, maximum); if (cursorVisible && NUMdefined (cursorFunctionValue)) FunctionEditor_drawCursorFunctionValue (me, cursorFunctionValue, Melder_float (Melder_half (cursorFunctionValue)), U""); Graphics_setColour (my d_graphics, Graphics_BLACK); Graphics_function (my d_graphics, sound -> z [ichan], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } else { Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, minimum * 32768, maximum * 32768); Graphics_function16 (my d_graphics, longSound -> buffer - longSound -> imin * nchan + (ichan - 1), nchan - 1, first, last, Sampled_indexToX (longSound, first), Sampled_indexToX (longSound, last)); } Graphics_resetViewport (my d_graphics, vp); } Graphics_setWindow (my d_graphics, 0.0, 1.0, 0.0, 1.0); Graphics_rectangle (my d_graphics, 0.0, 1.0, 0.0, 1.0); }
static autoStrings Strings_createAsFileOrDirectoryList (const char32 *path /* cattable */, int type) { #if USE_STAT /* * Initialize. */ DIR *d = nullptr; try { autoMelderString filePath, searchDirectory, left, right; /* * Parse the path. * Example: in /Users/paul/sounds/h*.wav", * the search directory is "/Users/paul/sounds", * the left environment is "h", and the right environment is ".wav". */ MelderString_copy (& searchDirectory, path); char32 *asterisk = str32rchr (searchDirectory. string, '*'); if (asterisk) { *asterisk = '\0'; searchDirectory. length = asterisk - searchDirectory. string; // probably superfluous, but correct char32 *lastSlash = str32rchr (searchDirectory. string, Melder_DIRECTORY_SEPARATOR); if (lastSlash) { *lastSlash = '\0'; // This fixes searchDirectory. searchDirectory. length = lastSlash - searchDirectory. string; // probably superfluous, but correct MelderString_copy (& left, lastSlash + 1); } else { MelderString_copy (& left, searchDirectory. string); // quickly save... MelderString_empty (& searchDirectory); // ...before destruction } MelderString_copy (& right, asterisk + 1); } char buffer8 [kMelder_MAXPATH+1]; Melder_str32To8bitFileRepresentation_inline (searchDirectory. string, buffer8); d = opendir (buffer8 [0] ? buffer8 : "."); if (! d) Melder_throw (U"Cannot open directory ", searchDirectory. string, U"."); //Melder_casual (U"opened"); autoStrings me = Thing_new (Strings); my strings = NUMvector <char32 *> (1, 1000000); struct dirent *entry; while (!! (entry = readdir (d))) { MelderString_copy (& filePath, searchDirectory. string [0] ? searchDirectory. string : U"."); MelderString_appendCharacter (& filePath, Melder_DIRECTORY_SEPARATOR); char32 buffer32 [kMelder_MAXPATH+1]; Melder_8bitFileRepresentationToStr32_inline (entry -> d_name, buffer32); MelderString_append (& filePath, buffer32); //Melder_casual (U"read ", filePath. string); Melder_str32To8bitFileRepresentation_inline (filePath. string, buffer8); struct stat stats; if (stat (buffer8, & stats) != 0) { //Melder_throw (U"Cannot look at file ", filePath. string, U"."); //stats. st_mode = -1L; } //Melder_casual (U"statted ", filePath. string); //Melder_casual (U"file ", filePath. string, U" mode ", stats. st_mode / 4096); if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && S_ISREG (stats. st_mode)) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && S_ISDIR (stats. st_mode))) { Melder_8bitFileRepresentationToStr32_inline (entry -> d_name, buffer32); int64 length = str32len (buffer32); if (buffer32 [0] != U'.' && (left. length == 0 || str32nequ (buffer32, left. string, left. length)) && (right. length == 0 || (length >= right. length && str32equ (buffer32 + (length - right. length), right. string)))) { my strings [++ my numberOfStrings] = Melder_dup (buffer32); } } } closedir (d); Strings_sort (me.get()); return me; } catch (MelderError) { if (d) closedir (d); // "finally" throw; } #elif defined (_WIN32) try { char32 searchPath [kMelder_MAXPATH+1]; int len = str32len (path); bool hasAsterisk = !! str32chr (path, U'*'); bool endsInSeparator = ( len != 0 && path [len - 1] == U'\\' ); autoStrings me = Thing_new (Strings); my strings = NUMvector <char32 *> (1, 1000000); Melder_sprint (searchPath, kMelder_MAXPATH+1, path, hasAsterisk || endsInSeparator ? U"" : U"\\", hasAsterisk ? U"" : U"*"); WIN32_FIND_DATAW findData; HANDLE searchHandle = FindFirstFileW (Melder_peek32toW (searchPath), & findData); if (searchHandle != INVALID_HANDLE_VALUE) { do { if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { if (findData. cFileName [0] != L'.') { my strings [++ my numberOfStrings] = Melder_dup (Melder_peekWto32 (findData. cFileName)); } } } while (FindNextFileW (searchHandle, & findData)); FindClose (searchHandle); } Strings_sort (me.get()); return me; } catch (MelderError) { throw; } #endif }
void TextGrid_anySound_alignInterval (TextGrid me, Function anySound, long tierNumber, long intervalNumber, const char32 *languageName, bool includeWords, bool includePhonemes) { try { IntervalTier headTier = TextGrid_checkSpecifiedTierIsIntervalTier (me, tierNumber); if (intervalNumber < 1 || intervalNumber > headTier -> intervals.size) Melder_throw (U"Interval ", intervalNumber, U" does not exist."); TextInterval interval = headTier -> intervals.at [intervalNumber]; if (! includeWords && ! includePhonemes) Melder_throw (U"Nothing to be done, because you asked neither for word alignment nor for phoneme alignment."); if (str32str (headTier -> name, U"/") ) Melder_throw (U"The current tier already has a slash (\"/\") in its name. Cannot create a word or phoneme tier from it."); autoSound part = anySound -> classInfo == classLongSound ? LongSound_extractPart (static_cast <LongSound> (anySound), interval -> xmin, interval -> xmax, true) : Sound_extractPart (static_cast <Sound> (anySound), interval -> xmin, interval -> xmax, kSound_windowShape_RECTANGULAR, 1.0, true); autoSpeechSynthesizer synthesizer = SpeechSynthesizer_create (languageName, U"default"); double silenceThreshold = -35, minSilenceDuration = 0.1, minSoundingDuration = 0.1; autoTextGrid analysis; if (! Melder_equ (interval -> text, U"")) { try { analysis = SpeechSynthesizer_and_Sound_and_TextInterval_align (synthesizer.get(), part.get(), interval, silenceThreshold, minSilenceDuration, minSoundingDuration); } catch (MelderError) { Melder_clearError (); // ignore all error messages from DTW and the like } } if (analysis) { /* * Clean up the analysis. */ Melder_assert (analysis -> xmin == interval -> xmin); Melder_assert (analysis -> xmax == interval -> xmax); Melder_assert (analysis -> tiers->size == 4); Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order."); IntervalTier_removeEmptyIntervals (analysisWordTier, nullptr); Melder_assert (analysisWordTier -> xmax == analysis -> xmax); Melder_assert (analysisWordTier -> intervals.size >= 1); TextInterval firstInterval = analysisWordTier -> intervals.at [1]; TextInterval lastInterval = analysisWordTier -> intervals.at [analysisWordTier -> intervals.size]; firstInterval -> xmin = analysis -> xmin; lastInterval -> xmax = analysis -> xmax; if (lastInterval -> xmax != analysis -> xmax) Melder_fatal (U"analysis ends at ", analysis -> xmax, U", but last interval at ", lastInterval -> xmax, U" seconds"); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (2)."); Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers->at [4]); if (! IntervalTier_check (analysisPhonemeTier)) Melder_throw (U"Analysis phoneme tier out of order."); IntervalTier_removeEmptyIntervals (analysisPhonemeTier, analysisWordTier); Melder_assert (analysisPhonemeTier -> xmax == analysis -> xmax); Melder_assert (analysisPhonemeTier -> intervals.size >= 1); firstInterval = analysisPhonemeTier -> intervals.at [1]; lastInterval = analysisPhonemeTier -> intervals.at [analysisPhonemeTier -> intervals.size]; firstInterval -> xmin = analysis -> xmin; lastInterval -> xmax = analysis -> xmax; Melder_assert (lastInterval -> xmax == analysis -> xmax); if (! IntervalTier_check (analysisPhonemeTier)) Melder_throw (U"Analysis phoneme tier out of order (2)."); } long wordTierNumber = 0, phonemeTierNumber = 0; IntervalTier wordTier = nullptr, phonemeTier = nullptr; /* * Include a word tier. */ if (includeWords) { /* * Make sure that the word tier exists. */ autoMelderString newWordTierName; MelderString_copy (& newWordTierName, headTier -> name, U"/word"); for (long itier = 1; itier <= my tiers->size; itier ++) { IntervalTier tier = static_cast <IntervalTier> (my tiers->at [itier]); if (Melder_equ (newWordTierName.string, tier -> name)) { if (tier -> classInfo != classIntervalTier) Melder_throw (U"A tier with the prospective word tier name (", tier -> name, U") already exists, but it is not an interval tier." U"\nPlease change its name or remove it."); wordTierNumber = itier; break; } } if (! wordTierNumber) { autoIntervalTier newWordTier = IntervalTier_create (my xmin, my xmax); Thing_setName (newWordTier.get(), newWordTierName.string); my tiers -> addItemAtPosition_move (newWordTier.move(), wordTierNumber = tierNumber + 1); } Melder_assert (wordTierNumber >= 1 && wordTierNumber <= my tiers->size); wordTier = static_cast <IntervalTier> (my tiers->at [wordTierNumber]); /* * Make sure that the word tier has boundaries at the edges of the interval. */ IntervalTier_insertIntervalDestructively (wordTier, interval -> xmin, interval -> xmax); /* * Copy the contents of the word analysis into the interval in the word tier. */ long wordIntervalNumber = IntervalTier_hasTime (wordTier, interval -> xmin); Melder_assert (wordIntervalNumber != 0); if (analysis) { Thing_cast (IntervalTier, analysisWordTier, analysis -> tiers->at [3]); if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (3)."); if (! IntervalTier_check (wordTier)) Melder_throw (U"Word tier out of order (3)."); for (long ianalysisInterval = 1; ianalysisInterval <= analysisWordTier -> intervals.size; ianalysisInterval ++) { TextInterval analysisInterval = analysisWordTier -> intervals.at [ianalysisInterval]; TextInterval wordInterval = nullptr; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { wordInterval = wordTier -> intervals.at [wordIntervalNumber]; TextInterval_setText (wordInterval, analysisInterval -> text); } else { wordInterval = wordTier -> intervals.at [wordIntervalNumber]; autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); wordInterval -> xmin = tmax; wordTier -> intervals. addItem_move (newInterval.move()); wordIntervalNumber ++; } } if (! IntervalTier_check (analysisWordTier)) Melder_throw (U"Analysis word tier out of order (4)."); if (! IntervalTier_check (wordTier)) Melder_throw (U"Word tier out of order (4)."); } } /* * Include a phoneme tier. */ if (includePhonemes) { /* * Make sure that the phoneme tier exists. */ autoMelderString newPhonemeTierName; MelderString_copy (& newPhonemeTierName, headTier -> name, U"/phon"); for (long itier = 1; itier <= my tiers->size; itier ++) { IntervalTier tier = (IntervalTier) my tiers->at [itier]; if (Melder_equ (newPhonemeTierName.string, tier -> name)) { if (tier -> classInfo != classIntervalTier) Melder_throw (U"A tier with the prospective phoneme tier name (", tier -> name, U") already exists, but it is not an interval tier." U"\nPlease change its name or remove it."); phonemeTierNumber = itier; break; } } if (! phonemeTierNumber) { autoIntervalTier newPhonemeTier = IntervalTier_create (my xmin, my xmax); Thing_setName (newPhonemeTier.get(), newPhonemeTierName.string); my tiers -> addItemAtPosition_move (newPhonemeTier.move(), phonemeTierNumber = wordTierNumber ? wordTierNumber + 1 : tierNumber + 1); } Melder_assert (phonemeTierNumber >= 1 && phonemeTierNumber <= my tiers->size); phonemeTier = static_cast <IntervalTier> (my tiers->at [phonemeTierNumber]); /* * Make sure that the phoneme tier has boundaries at the edges of the interval. */ IntervalTier_insertIntervalDestructively (phonemeTier, interval -> xmin, interval -> xmax); /* * Copy the contents of the phoneme analysis into the interval in the phoneme tier. */ long phonemeIntervalNumber = IntervalTier_hasTime (phonemeTier, interval -> xmin); Melder_assert (phonemeIntervalNumber != 0); if (analysis.get()) { Thing_cast (IntervalTier, analysisPhonemeTier, analysis -> tiers->at [4]); for (long ianalysisInterval = 1; ianalysisInterval <= analysisPhonemeTier -> intervals.size; ianalysisInterval ++) { TextInterval analysisInterval = analysisPhonemeTier -> intervals.at [ianalysisInterval]; TextInterval phonemeInterval = nullptr; double tmin = analysisInterval -> xmin, tmax = analysisInterval -> xmax; if (tmax == analysis -> xmax) { phonemeInterval = phonemeTier -> intervals.at [phonemeIntervalNumber]; TextInterval_setText (phonemeInterval, analysisInterval -> text); } else { phonemeInterval = phonemeTier -> intervals.at [phonemeIntervalNumber]; autoTextInterval newInterval = TextInterval_create (tmin, tmax, analysisInterval -> text); phonemeInterval -> xmin = tmax; phonemeTier -> intervals. addItem_move (newInterval.move()); phonemeIntervalNumber ++; } } } if (includeWords) { /* * Synchronize the boundaries between the word tier and the phoneme tier. */ //for (long iinterval = 1; iinterval <= } } } catch (MelderError) { Melder_throw (me, U" & ", anySound, U": interval not aligned."); } }
int Praat_tests (int itest, char32 *arg1, char32 *arg2, char32 *arg3, char32 *arg4) { int64 n = Melder_atoi (arg1); double t; (void) arg1; (void) arg2; (void) arg3; (void) arg4; Melder_clearInfo (); Melder_stopwatch (); switch (itest) { case kPraatTests_TIME_RANDOM_FRACTION: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomFraction (); t = Melder_stopwatch (); } break; case kPraatTests_TIME_RANDOM_GAUSS: { for (int64 i = 1; i <= n; i ++) (void) NUMrandomGauss (0.0, 1.0); t = Melder_stopwatch (); } break; case kPraatTests_TIME_SORT: { long m = Melder_atoi (arg2); long *array = NUMvector <long> (1, m); for (int64 i = 1; i <= m; i ++) array [i] = NUMrandomInteger (1, 100); Melder_stopwatch (); for (int64 i = 1; i <= n; i ++) NUMsort_l (m, array); t = Melder_stopwatch (); NUMvector_free (array, 1); } break; case kPraatTests_TIME_INTEGER: { double sum = 0; for (int64 i = 1; i <= n; i ++) sum += i * (i - 1) * (i - 2); t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT: { double sum = 0.0, fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += fi * (fi - 1.0) * (fi - 2.0); t = Melder_stopwatch (); MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_BUILTIN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32_t) fi; t = Melder_stopwatch (); // 2.59 // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_FLOAT_TO_UNSIGNED_EXTERN: { uint64_t sum = 0; double fn = n; for (double fi = 1.0; fi <= fn; fi = fi + 1.0) sum += (uint32_t) ((int32_t) (fi - 2147483648.0) + 2147483647L + 1); t = Melder_stopwatch (); // 1.60 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_BUILTIN: { double sum = 0.0; uint32_t nu = (uint32_t) n; for (uint32_t iu = 1; iu <= nu; iu ++) sum += (double) iu; t = Melder_stopwatch (); // 1.35 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_UNSIGNED_TO_FLOAT_EXTERN: { double sum = 0.0; uint32_t nu = (uint32_t) n; for (uint32_t iu = 1; iu <= nu; iu ++) sum += (double) (int32_t) (iu - 2147483647L - 1) + 2147483648.0; t = Melder_stopwatch (); // 0.96 MelderInfo_writeLine (sum); } break; case kPraatTests_TIME_STRING_MELDER_32: { autoMelderString string; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { MelderString_copy (& string, word); for (int j = 1; j <= 30; j ++) MelderString_append (& string, word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_S: { std::string s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_C: { std::basic_string<char> s = ""; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WS: { std::wstring s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_WC: { std::basic_string<wchar_t> s = L""; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_32: { std::basic_string<char32_t> s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRING_CPP_U32STRING: { #if ! defined (macintosh) || ! useCarbon std::u32string s = U""; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { s = word; for (int j = 1; j <= 30; j ++) s += word; } #endif t = Melder_stopwatch (); } break; case kPraatTests_TIME_STRCPY: { char buffer [100]; char word [] { "abc" }; word [2] = (char) NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { strcpy (buffer, word); for (int j = 1; j <= 30; j ++) strcpy (buffer + strlen (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (Melder_peek8to32 (buffer)); } break; case kPraatTests_TIME_WCSCPY: { wchar_t buffer [100]; wchar_t word [] { L"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { wcscpy (buffer, word); for (int j = 1; j <= 30; j ++) wcscpy (buffer + wcslen (buffer), word); } t = Melder_stopwatch (); } break; case kPraatTests_TIME_STR32CPY: { char32 buffer [100]; char32 word [] { U"abc" }; word [2] = NUMrandomInteger ('a', 'z'); for (int64 i = 1; i <= n; i ++) { str32cpy (buffer, word); for (int j = 1; j <= 30; j ++) str32cpy (buffer + str32len (buffer), word); } t = Melder_stopwatch (); MelderInfo_writeLine (buffer); } break; case kPraatTests_TIME_GRAPHICS_TEXT_TOP: { autoPraatPicture picture; for (int64 i = 1; i <= n; i ++) { Graphics_textTop (GRAPHICS, false, U"hello world"); } t = Melder_stopwatch (); } break; } MelderInfo_writeLine (Melder_single (t / n * 1e9), U" nanoseconds"); MelderInfo_close (); return 1; }
static Strings Strings_createAsFileOrDirectoryList (const wchar_t *path, int type) { #if USE_STAT /* * Initialize. */ DIR *d = NULL; try { autoMelderString filePath, searchDirectory, left, right; /* * Parse the path. * Example: in /Users/paul/sounds/h*.wav", * the search directory is "/Users/paul/sounds", * the left environment is "h", and the right environment is ".wav". */ MelderString_copy (& searchDirectory, path); wchar_t *asterisk = wcsrchr (searchDirectory. string, '*'); if (asterisk != NULL) { *asterisk = '\0'; searchDirectory. length = asterisk - searchDirectory. string; // probably superfluous, but correct wchar_t *lastSlash = wcsrchr (searchDirectory. string, Melder_DIRECTORY_SEPARATOR); if (lastSlash != NULL) { *lastSlash = '\0'; // This fixes searchDirectory. searchDirectory. length = lastSlash - searchDirectory. string; // probably superfluous, but correct MelderString_copy (& left, lastSlash + 1); } else { MelderString_copy (& left, searchDirectory. string); // quickly save... MelderString_empty (& searchDirectory); // ...before destruction } MelderString_copy (& right, asterisk + 1); } char buffer8 [1+kMelder_MAXPATH]; Melder_wcsTo8bitFileRepresentation_inline (searchDirectory. string, buffer8); d = opendir (buffer8 [0] ? buffer8 : "."); if (d == NULL) Melder_throw ("Cannot open directory ", searchDirectory. string, "."); //Melder_casual ("opened"); autoStrings me = Thing_new (Strings); my strings = NUMvector <wchar_t *> (1, 1000000); struct dirent *entry; while ((entry = readdir (d)) != NULL) { MelderString_copy (& filePath, searchDirectory. string [0] ? searchDirectory. string : L"."); MelderString_appendCharacter (& filePath, Melder_DIRECTORY_SEPARATOR); wchar_t bufferW [1+kMelder_MAXPATH]; Melder_8bitFileRepresentationToWcs_inline (entry -> d_name, bufferW); MelderString_append (& filePath, bufferW); //Melder_casual ("read %s", filePath. string); Melder_wcsTo8bitFileRepresentation_inline (filePath. string, buffer8); struct stat stats; if (stat (buffer8, & stats) != 0) { Melder_throw ("Cannot look at file ", filePath. string, "."); //stats. st_mode = -1L; } //Melder_casual ("statted %s", filePath. string); //Melder_casual ("file %s mode %s", filePath. string, Melder_integer (stats. st_mode / 4096)); if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && S_ISREG (stats. st_mode)) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && S_ISDIR (stats. st_mode))) { Melder_8bitFileRepresentationToWcs_inline (entry -> d_name, bufferW); unsigned long length = wcslen (bufferW); if (bufferW [0] != '.' && (left. length == 0 || wcsnequ (bufferW, left. string, left. length)) && (right. length == 0 || (length >= right. length && wcsequ (bufferW + (length - right. length), right. string)))) { my strings [++ my numberOfStrings] = Melder_wcsdup (bufferW); } } } closedir (d); Strings_sort (me.peek()); return me.transfer(); } catch (MelderError) { if (d) closedir (d); // "finally" throw; } #elif defined (_WIN32) try { wchar_t searchPath [1+kMelder_MAXPATH]; int len = wcslen (path), hasAsterisk = wcschr (path, '*') != NULL, endsInSeparator = len != 0 && path [len - 1] == '\\'; autoStrings me = Thing_new (Strings); my strings = NUMvector <wchar_t *> (1, 1000000); swprintf (searchPath, 1+kMelder_MAXPATH, L"%ls%ls%ls", path, hasAsterisk || endsInSeparator ? L"" : L"\\", hasAsterisk ? L"" : L"*"); WIN32_FIND_DATAW findData; HANDLE searchHandle = FindFirstFileW (searchPath, & findData); if (searchHandle != INVALID_HANDLE_VALUE) { do { if ((type == Strings_createAsFileOrDirectoryList_TYPE_FILE && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) || (type == Strings_createAsFileOrDirectoryList_TYPE_DIRECTORY && (findData. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { if (findData. cFileName [0] != '.') { my strings [++ my numberOfStrings] = Melder_wcsdup (findData. cFileName); } } } while (FindNextFileW (searchHandle, & findData)); FindClose (searchHandle); } Strings_sort (me.peek()); return me.transfer(); } catch (MelderError) { throw; } #endif }