mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 08:59:28 +02:00
Line breaks allowed in strings (or lists) in $ lines; \n means n ...
... because we must match how xgettext parses strings, and unlike XLisp, it does it strictly according to this reference: http://www.lispworks.com/documentation/lw70/CLHS/Body/02_de.htm
This commit is contained in:
parent
ad4843621b
commit
ff3a869e83
@ -1471,27 +1471,28 @@ wxString NyquistEffect::EscapeString(const wxString & inStr)
|
|||||||
|
|
||||||
wxArrayString NyquistEffect::ParseChoice(const wxString & text)
|
wxArrayString NyquistEffect::ParseChoice(const wxString & text)
|
||||||
{
|
{
|
||||||
wxArrayString choices;
|
|
||||||
if (text[0] == wxT('(')) {
|
if (text[0] == wxT('(')) {
|
||||||
// New style: expecting a Lisp-like list of strings
|
// New style: expecting a Lisp-like list of strings
|
||||||
Tokenize(text, choices, 1, 1);
|
Tokenizer tzer;
|
||||||
|
tzer.Tokenize(text, true, 1, 1);
|
||||||
|
auto &choices = tzer.tokens;
|
||||||
for (auto &choice : choices)
|
for (auto &choice : choices)
|
||||||
choice = UnQuote(choice);
|
choice = UnQuote(choice);
|
||||||
|
return choices;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Old style: expecting a comma-separated list of
|
// Old style: expecting a comma-separated list of
|
||||||
// un-internationalized names, ignoring leading and trailing spaces
|
// un-internationalized names, ignoring leading and trailing spaces
|
||||||
// on each; and the whole may be quoted
|
// on each; and the whole may be quoted
|
||||||
choices = wxStringTokenize(
|
auto choices = wxStringTokenize(
|
||||||
text[0] == wxT('"') ? text.Mid(1, text.Length() - 2) : text,
|
text[0] == wxT('"') ? text.Mid(1, text.Length() - 2) : text,
|
||||||
wxT(",")
|
wxT(",")
|
||||||
);
|
);
|
||||||
for (auto &choice : choices)
|
for (auto &choice : choices)
|
||||||
choice = choice.Trim(true).Trim(false);
|
choice = choice.Trim(true).Trim(false);
|
||||||
}
|
|
||||||
|
|
||||||
return choices;
|
return choices;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NyquistEffect::RedirectOutput()
|
void NyquistEffect::RedirectOutput()
|
||||||
{
|
{
|
||||||
@ -1530,8 +1531,9 @@ wxString NyquistEffect::UnQuote(
|
|||||||
}
|
}
|
||||||
else if (allowParens &&
|
else if (allowParens &&
|
||||||
len >= 2 && s[0] == wxT('(') && s[len - 1] == wxT(')')) {
|
len >= 2 && s[0] == wxT('(') && s[len - 1] == wxT(')')) {
|
||||||
wxArrayString tokens;
|
Tokenizer tzer;
|
||||||
Tokenize(s, tokens, 1, 1);
|
tzer.Tokenize(s, true, 1, 1);
|
||||||
|
auto &tokens = tzer.tokens;
|
||||||
if (tokens.size() > 1)
|
if (tokens.size() > 1)
|
||||||
// Assume the first token was _ -- we don't check that
|
// Assume the first token was _ -- we don't check that
|
||||||
// And the second is the string, which is internationalized
|
// And the second is the string, which is internationalized
|
||||||
@ -1564,15 +1566,10 @@ double NyquistEffect::GetCtrlValue(const wxString &s)
|
|||||||
return Internat::CompatibleToDouble(s);
|
return Internat::CompatibleToDouble(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NyquistEffect::Tokenize(
|
bool NyquistEffect::Tokenizer::Tokenize(
|
||||||
const wxString &line, wxArrayString &tokens,
|
const wxString &line, bool eof,
|
||||||
size_t trimStart, size_t trimEnd)
|
size_t trimStart, size_t trimEnd)
|
||||||
{
|
{
|
||||||
bool sl = false;
|
|
||||||
bool q = false;
|
|
||||||
wxString tok = wxT("");
|
|
||||||
int paren = 0;
|
|
||||||
|
|
||||||
auto endToken = [&]{
|
auto endToken = [&]{
|
||||||
if (!tok.empty()) {
|
if (!tok.empty()) {
|
||||||
tokens.push_back(tok);
|
tokens.push_back(tok);
|
||||||
@ -1587,8 +1584,6 @@ void NyquistEffect::Tokenize(
|
|||||||
sl = true;
|
sl = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (sl && c == wxT('n'))
|
|
||||||
c = wxT('\n');
|
|
||||||
|
|
||||||
if (!sl && !paren && c == wxT('"')) {
|
if (!sl && !paren && c == wxT('"')) {
|
||||||
if (!q)
|
if (!q)
|
||||||
@ -1626,18 +1621,29 @@ void NyquistEffect::Tokenize(
|
|||||||
sl = false;
|
sl = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish -- this just forgives unbalanced open quotes or left parens
|
if (eof || (!q && !paren)) {
|
||||||
endToken();
|
endToken();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// End of line but not of file, and a string or list is yet unclosed
|
||||||
|
// If a string, accumulate a newline character
|
||||||
|
if (q)
|
||||||
|
tok += wxT('\n');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NyquistEffect::Parse(const wxString &line)
|
bool NyquistEffect::Parse(
|
||||||
|
Tokenizer &tzer, const wxString &line, bool eof, bool first)
|
||||||
{
|
{
|
||||||
wxArrayString tokens;
|
if ( !tzer.Tokenize(line, eof, first ? 1 : 0, 0) )
|
||||||
Tokenize(line, tokens, 1, 0);
|
return false;
|
||||||
|
|
||||||
|
const auto &tokens = tzer.tokens;
|
||||||
int len = tokens.size();
|
int len = tokens.size();
|
||||||
if (len < 1) {
|
if (len < 1) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consistency decision is for "plug-in" as the correct spelling
|
// Consistency decision is for "plug-in" as the correct spelling
|
||||||
@ -1645,7 +1651,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
if (len == 2 && tokens[0] == wxT("nyquist") &&
|
if (len == 2 && tokens[0] == wxT("nyquist") &&
|
||||||
(tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin"))) {
|
(tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin"))) {
|
||||||
mOK = true;
|
mOK = true;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("type")) {
|
if (len >= 2 && tokens[0] == wxT("type")) {
|
||||||
@ -1661,7 +1667,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
if (len >= 3 && tokens[2] == wxT("spectral")) {;
|
if (len >= 3 && tokens[2] == wxT("spectral")) {;
|
||||||
mIsSpectral = true;
|
mIsSpectral = true;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 2 && tokens[0] == wxT("codetype")) {
|
if (len == 2 && tokens[0] == wxT("codetype")) {
|
||||||
@ -1674,7 +1680,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
mIsSal = true;
|
mIsSal = true;
|
||||||
mFoundType = true;
|
mFoundType = true;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update documentation.
|
// TODO: Update documentation.
|
||||||
@ -1696,7 +1702,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
mCompiler = false;
|
mCompiler = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We support versions 1, 2 and 3
|
// We support versions 1, 2 and 3
|
||||||
@ -1713,7 +1719,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
_("This version of Audacity does not support Nyquist plug-in version %ld"),
|
_("This version of Audacity does not support Nyquist plug-in version %ld"),
|
||||||
v
|
v
|
||||||
);
|
);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
mVersion = (int) v;
|
mVersion = (int) v;
|
||||||
}
|
}
|
||||||
@ -1722,17 +1728,17 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
mName = UnQuote(tokens[1]);
|
mName = UnQuote(tokens[1]);
|
||||||
if (mName.EndsWith(wxT("...")))
|
if (mName.EndsWith(wxT("...")))
|
||||||
mName = mName.RemoveLast(3);
|
mName = mName.RemoveLast(3);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("action")) {
|
if (len >= 2 && tokens[0] == wxT("action")) {
|
||||||
mAction = UnQuote(tokens[1]);
|
mAction = UnQuote(tokens[1]);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("info")) {
|
if (len >= 2 && tokens[0] == wxT("info")) {
|
||||||
mInfo = UnQuote(tokens[1]);
|
mInfo = UnQuote(tokens[1]);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("preview")) {
|
if (len >= 2 && tokens[0] == wxT("preview")) {
|
||||||
@ -1751,7 +1757,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
else if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
|
else if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
|
||||||
mEnablePreview = false;
|
mEnablePreview = false;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximum number of samples to be processed. This can help the
|
// Maximum number of samples to be processed. This can help the
|
||||||
@ -1768,7 +1774,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
// -1 = auto (default), 0 = don't merge clips, 1 = do merge clips
|
// -1 = auto (default), 0 = don't merge clips, 1 = do merge clips
|
||||||
tokens[1].ToLong(&v);
|
tokens[1].ToLong(&v);
|
||||||
mMergeClips = v;
|
mMergeClips = v;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("restoresplits")) {
|
if (len >= 2 && tokens[0] == wxT("restoresplits")) {
|
||||||
@ -1776,18 +1782,18 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
// Splits are restored by default. Set to 0 to prevent.
|
// Splits are restored by default. Set to 0 to prevent.
|
||||||
tokens[1].ToLong(&v);
|
tokens[1].ToLong(&v);
|
||||||
mRestoreSplits = !!v;
|
mRestoreSplits = !!v;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("author")) {
|
if (len >= 2 && tokens[0] == wxT("author")) {
|
||||||
mAuthor = UnQuote(tokens[1]);
|
mAuthor = UnQuote(tokens[1]);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2 && tokens[0] == wxT("copyright")) {
|
if (len >= 2 && tokens[0] == wxT("copyright")) {
|
||||||
mCopyright = UnQuote(tokens[1]);
|
mCopyright = UnQuote(tokens[1]);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document.
|
// TODO: Document.
|
||||||
@ -1795,7 +1801,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
if (len >= 2 && tokens[0] == wxT("manpage")) {
|
if (len >= 2 && tokens[0] == wxT("manpage")) {
|
||||||
// do not translate
|
// do not translate
|
||||||
mManPage = UnQuote(tokens[1], false, false);
|
mManPage = UnQuote(tokens[1], false, false);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document.
|
// TODO: Document.
|
||||||
@ -1803,7 +1809,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
if (len >= 2 && tokens[0] == wxT("helpfile")) {
|
if (len >= 2 && tokens[0] == wxT("helpfile")) {
|
||||||
// do not translate
|
// do not translate
|
||||||
mHelpFile = UnQuote(tokens[1], false, false);
|
mHelpFile = UnQuote(tokens[1], false, false);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document.
|
// TODO: Document.
|
||||||
@ -1812,7 +1818,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
|
if (tokens[1] == wxT("disabled") || tokens[1] == wxT("false")) {
|
||||||
mDebugButton = false;
|
mDebugButton = false;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 6 && tokens[0] == wxT("control")) {
|
if (len >= 6 && tokens[0] == wxT("control")) {
|
||||||
@ -1845,7 +1851,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
ctrl.label = UnQuote( ctrl.label );
|
ctrl.label = UnQuote( ctrl.label );
|
||||||
|
|
||||||
if (len < 8) {
|
if (len < 8) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tokens[3] == wxT("float")) ||
|
if ((tokens[3] == wxT("float")) ||
|
||||||
@ -1869,7 +1875,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
// Note that the AudacityApp's mLogger has not yet been created,
|
// Note that the AudacityApp's mLogger has not yet been created,
|
||||||
// so this brings up an alert box, but after the Audacity frame is up.
|
// so this brings up an alert box, but after the Audacity frame is up.
|
||||||
wxLogWarning(str);
|
wxLogWarning(str);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl.lowStr = tokens[6];
|
ctrl.lowStr = tokens[6];
|
||||||
@ -1924,6 +1930,7 @@ void NyquistEffect::Parse(const wxString &line)
|
|||||||
mCategories.Add(tokens[i]);
|
mCategories.Add(tokens[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NyquistEffect::ParseProgram(wxInputStream & stream)
|
bool NyquistEffect::ParseProgram(wxInputStream & stream)
|
||||||
@ -1952,17 +1959,28 @@ bool NyquistEffect::ParseProgram(wxInputStream & stream)
|
|||||||
mFoundType = false;
|
mFoundType = false;
|
||||||
while (!stream.Eof() && stream.IsOk())
|
while (!stream.Eof() && stream.IsOk())
|
||||||
{
|
{
|
||||||
|
bool dollar = false;
|
||||||
wxString line = pgm.ReadLine().Trim(false);
|
wxString line = pgm.ReadLine().Trim(false);
|
||||||
if (line.Length() > 1 &&
|
if (line.Length() > 1 &&
|
||||||
// New in 2.3.0: allow magic comment lines to start with $
|
// New in 2.3.0: allow magic comment lines to start with $
|
||||||
// The trick is that xgettext will not consider such lines comments
|
// The trick is that xgettext will not consider such lines comments
|
||||||
// and will extract the strings they contain
|
// and will extract the strings they contain
|
||||||
(line[0] == wxT(';') || line[0] == wxT('$')))
|
(line[0] == wxT(';') ||
|
||||||
|
(dollar = (line[0] == wxT('$')))))
|
||||||
{
|
{
|
||||||
Parse(line);
|
Tokenizer tzer;
|
||||||
// Don't pass this line to the interpreter, so it doesn't get confused
|
unsigned nLines = 1;
|
||||||
// by $, but pass a blank,
|
bool done;
|
||||||
|
do
|
||||||
|
// Allow run-ons only for new $ format header lines
|
||||||
|
done = Parse(tzer, line, !dollar || stream.Eof(), nLines == 1);
|
||||||
|
while(!done &&
|
||||||
|
(line = pgm.ReadLine().Trim(false), ++nLines, true));
|
||||||
|
|
||||||
|
// Don't pass these lines to the interpreter, so it doesn't get confused
|
||||||
|
// by $, but pass blanks,
|
||||||
// so that SAL effects compile with proper line numbers
|
// so that SAL effects compile with proper line numbers
|
||||||
|
while (nLines --)
|
||||||
mCmd += wxT('\n');
|
mCmd += wxT('\n');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -163,10 +163,18 @@ private:
|
|||||||
void ParseFile();
|
void ParseFile();
|
||||||
bool ParseCommand(const wxString & cmd);
|
bool ParseCommand(const wxString & cmd);
|
||||||
bool ParseProgram(wxInputStream & stream);
|
bool ParseProgram(wxInputStream & stream);
|
||||||
static void Tokenize(
|
struct Tokenizer {
|
||||||
const wxString &line, wxArrayString &tokens,
|
bool sl { false };
|
||||||
|
bool q { false };
|
||||||
|
int paren{ 0 };
|
||||||
|
wxString tok;
|
||||||
|
wxArrayString tokens;
|
||||||
|
|
||||||
|
bool Tokenize(
|
||||||
|
const wxString &line, bool eof,
|
||||||
size_t trimStart, size_t trimEnd);
|
size_t trimStart, size_t trimEnd);
|
||||||
void Parse(const wxString &line);
|
};
|
||||||
|
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first);
|
||||||
|
|
||||||
static wxString UnQuote(const wxString &s,
|
static wxString UnQuote(const wxString &s,
|
||||||
bool allowParens = true, bool translate = true);
|
bool allowParens = true, bool translate = true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user