Forward port from 2.6 branch to avoid wxSTD usage crashes.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38143 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Włodzimierz Skiba
2006-03-16 13:06:39 +00:00
parent 7487919e55
commit 9c9691ba24
4 changed files with 361 additions and 247 deletions

View File

@@ -301,81 +301,84 @@ void ForbidWarning(TexMacroDef *def)
TexMacroDef *MatchMacro(wxChar *buffer, int *pos, wxChar **env, bool *parseToBrace)
{
*parseToBrace = true;
int i = (*pos);
TexMacroDef *def = NULL;
wxChar macroBuf[40];
*parseToBrace = true;
int i = (*pos);
TexMacroDef *def = NULL;
wxChar macroBuf[40];
// First, try to find begin{thing}
if (wxStrncmp(buffer+i, _T("begin{"), 6) == 0)
{
i += 6;
int j = i;
while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
// First, try to find begin{thing}
if (wxStrncmp(buffer+i, _T("begin{"), 6) == 0)
{
macroBuf[j-i] = buffer[j];
j ++;
i += 6;
int j = i;
while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
{
macroBuf[j-i] = buffer[j];
j ++;
}
macroBuf[j-i] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
if (def)
{
*pos = j + 1; // BUGBUG Should this be + 1???
*env = def->name;
ForbidWarning(def);
return def;
}
else
{
return NULL;
}
}
// Failed, so try to find macro from definition list
int j = i;
// First try getting a one-character macro, but ONLY
// if these TWO characters are not both alphabetical (could
// be a longer macro)
if (!(isalpha(buffer[i]) && isalpha(buffer[i+1])))
{
macroBuf[0] = buffer[i];
macroBuf[1] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
if (def) j ++;
}
if (!def)
{
while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
{
macroBuf[j-i] = buffer[j];
j ++;
}
macroBuf[j-i] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
}
macroBuf[j-i] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
if (def)
{
*pos = j + 1; // BUGBUG Should this be + 1???
*env = def->name;
ForbidWarning(def);
return def;
i = j;
// We want to check whether this is a space-consuming macro
// (e.g. {\bf word})
// No brace, e.g. \input thing.tex instead of \input{thing};
// or a numeric argument, such as \parindent0pt
if ((def->no_args > 0) && ((buffer[i] == 32) || (buffer[i] == '=') || (isdigit(buffer[i]))))
{
if ((buffer[i] == 32) || (buffer[i] == '='))
i ++;
*parseToBrace = false;
}
*pos = i;
ForbidWarning(def);
return def;
}
else return NULL;
}
// Failed, so try to find macro from definition list
int j = i;
// First try getting a one-character macro, but ONLY
// if these TWO characters are not both alphabetical (could
// be a longer macro)
if (!(isalpha(buffer[i]) && isalpha(buffer[i+1])))
{
macroBuf[0] = buffer[i];
macroBuf[1] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
if (def) j ++;
}
if (!def)
{
while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
{
macroBuf[j-i] = buffer[j];
j ++;
}
macroBuf[j-i] = 0;
def = (TexMacroDef *)MacroDefs.Get(macroBuf);
}
if (def)
{
i = j;
// We want to check whether this is a space-consuming macro
// (e.g. {\bf word})
// No brace, e.g. \input thing.tex instead of \input{thing};
// or a numeric argument, such as \parindent0pt
if ((def->no_args > 0) && ((buffer[i] == 32) || (buffer[i] == '=') || (isdigit(buffer[i]))))
{
if ((buffer[i] == 32) || (buffer[i] == '='))
i ++;
*parseToBrace = false;
}
*pos = i;
ForbidWarning(def);
return def;
}
return NULL;
return NULL;
}
void EatWhiteSpace(wxChar *buffer, int *pos)
@@ -1271,16 +1274,20 @@ int ParseArg(TexChunk *thisArg, wxList& children, wxChar *buffer, int pos, wxCha
children.Append((wxObject *)chunk);
// Eliminate newline after a \begin{} or a \\ if possible
if (env || wxStrcmp(def->name, _T("\\")) == 0)
if (buffer[pos] == 13)
{
if ((env || wxStrcmp(def->name, _T("\\")) == 0) && (buffer[pos] == 13))
{
pos ++;
if (buffer[pos] == 10)
pos ++;
}
}
pos = ParseMacroBody(def->name, chunk, chunk->no_args,
buffer, pos, env, tmpParseToBrace, customMacroArgs);
pos = ParseMacroBody(def->name,
chunk, chunk->no_args,
buffer,
pos,
env,
tmpParseToBrace,
customMacroArgs);
// If custom macro, parse the body substituting the above found args.
if (customMacro)

View File

@@ -14,6 +14,8 @@
#include "wx/list.h"
#include "wx/hash.h"
#include "wx/tokenzr.h"
#include "wx/wfstream.h"
#include "wx/txtstrm.h"
#include "wxhlpblk.h"
/*
@@ -176,7 +178,7 @@ extern wxPathList TexPathList; // Path list, can be used for file searching
extern bool StringMatch(const wxChar *one, const wxChar *two, bool subString = true, bool exact = false);
// Define a variable value from the .ini file
wxChar *RegisterSetting(wxChar *settingName, wxChar *settingValue, bool interactive = true);
wxChar *RegisterSetting(const wxString& settingName, const wxString& settingValue, bool interactive = true);
// Major document styles
#define LATEX_REPORT 1
@@ -500,23 +502,23 @@ extern wxList CustomMacroList;
class CustomMacro: public wxObject
{
public:
wxChar *macroName;
wxChar *macroBody;
int noArgs;
inline CustomMacro(wxChar *name, int args, wxChar *body)
{
noArgs = args;
macroName = wxStrcpy(new wxChar[wxStrlen(name) + 1], name);
if (body)
macroBody = wxStrcpy(new wxChar[wxStrlen(body) + 1], body);
else
macroBody = NULL;
}
~CustomMacro();
public:
wxChar *macroName;
wxChar *macroBody;
int noArgs;
inline CustomMacro(const wxChar *name, int args, wxChar *body)
{
noArgs = args;
macroName = wxStrcpy(new wxChar[wxStrlen(name) + 1], name);
if (body)
macroBody = wxStrcpy(new wxChar[wxStrlen(body) + 1], body);
else
macroBody = NULL;
}
~CustomMacro();
};
bool ReadCustomMacros(wxChar *filename);
bool ReadCustomMacros(const wxString& filename);
void ShowCustomMacros(void);
CustomMacro *FindCustomMacro(wxChar *name);
wxChar *ParseMultifieldString(wxChar *s, int *pos);
@@ -1066,6 +1068,3 @@ extern void InitialiseColourTable(void);
#define ltTOPLEVEL 15000
#define ltCUSTOM_MACRO 15001
#define ltSOLO_BLOCK 15002

View File

@@ -402,7 +402,7 @@ bool MyApp::OnInit()
wxString path = TexPathList.FindValidPath(MacroFile);
if (!path.empty())
ReadCustomMacros((wxChar *)path.c_str());
ReadCustomMacros(path);
#if wxUSE_STATUSBAR
wxString inStr(_T("In "));
@@ -444,7 +444,7 @@ bool MyApp::OnInit()
wxString path = TexPathList.FindValidPath(MacroFile);
if (!path.empty())
ReadCustomMacros((wxChar*)path.c_str());
ReadCustomMacros(path);
Go();
if (runTwice)
@@ -758,7 +758,7 @@ void MyFrame::OnLoadMacros(wxCommandEvent& WXUNUSED(event))
if (!s.empty() && wxFileExists(s))
{
MacroFile = copystring(s);
ReadCustomMacros((wxChar *)s.c_str());
ReadCustomMacros(s);
ShowCustomMacros();
}
#endif // wxUSE_FILEDLG

View File

@@ -483,6 +483,22 @@ void ReadTexReferences(wxChar *filename)
*
*/
void BibEatWhiteSpace(wxString& line)
{
while(!line.empty() && (line[0] == _T(' ') || line[0] == _T('\t') || line[0] == (wxChar)EOF))
{
if (line[0] == 10)
BibLine ++;
line = line.substr(1);
}
// Ignore end-of-line comments
if (line[0] == _T('%') || line[0] == _T(';') || line[0] == _T('#'))
{
line = wxEmptyString;
}
}
void BibEatWhiteSpace(wxSTD istream& str)
{
char ch = (char)str.peek();
@@ -511,6 +527,24 @@ void BibEatWhiteSpace(wxSTD istream& str)
}
// Read word up to { or , or space
wxString BibReadWord(wxString& line)
{
wxString val;
while (!line.empty() &&
line[0] != _T('\t') &&
line[0] != _T(' ') &&
line[0] != _T('{') &&
line[0] != _T('(') &&
line[0] != _T(',') &&
line[0] != _T('='))
{
val << line[0];
line = line.substr(1);
}
return val;
}
void BibReadWord(wxSTD istream& istr, wxChar *buffer)
{
int i = 0;
@@ -528,85 +562,163 @@ void BibReadWord(wxSTD istream& istr, wxChar *buffer)
}
// Read string (double-quoted or not) to end quote or EOL
wxString BibReadToEOL(wxString& line)
{
if(line.empty())
return wxEmptyString;
wxString val;
bool inQuotes = false;
if (line[0] == _T('"'))
{
line = line.substr(1);
inQuotes = true;
}
// If in quotes, read white space too. If not,
// stop at white space or comment.
while (!line.empty() && line[0] != _T('"') &&
(inQuotes || ((line[0] != _T(' ')) && (line[0] != 9) &&
(line[0] != _T(';')) && (line[0] != _T('%')) && (line[0] != _T('#')))))
{
val << line[0];
line = line.substr(1);
}
if (line[0] == '"')
line = line.substr(1);
return val;
}
void BibReadToEOL(wxSTD istream& istr, wxChar *buffer)
{
int i = 0;
buffer[i] = 0;
char ch = (char)istr.peek();
bool inQuotes = false;
if (ch == '"')
{
istr.get(ch);
ch = (char)istr.peek();
inQuotes = true;
}
// If in quotes, read white space too. If not,
// stop at white space or comment.
while (!istr.eof() && ch != 13 && ch != 10 && ch != _T('"') &&
(inQuotes || ((ch != _T(' ')) && (ch != 9) &&
(ch != _T(';')) && (ch != _T('%')) && (ch != _T('#')))))
{
istr.get(ch);
buffer[i] = ch;
i ++;
ch = (char)istr.peek();
}
if (ch == '"')
istr.get(ch);
buffer[i] = 0;
int i = 0;
buffer[i] = 0;
char ch = (char)istr.peek();
bool inQuotes = false;
if (ch == '"')
{
istr.get(ch);
ch = (char)istr.peek();
inQuotes = true;
}
// If in quotes, read white space too. If not,
// stop at white space or comment.
while (!istr.eof() && ch != 13 && ch != 10 && ch != _T('"') &&
(inQuotes || ((ch != _T(' ')) && (ch != 9) &&
(ch != _T(';')) && (ch != _T('%')) && (ch != _T('#')))))
{
istr.get(ch);
buffer[i] = ch;
i ++;
ch = (char)istr.peek();
}
if (ch == '"')
istr.get(ch);
buffer[i] = 0;
}
// Read }-terminated value, taking nested braces into account.
wxString BibReadValue(wxString& line,
bool ignoreBraces = true,
bool quotesMayTerminate = true)
{
wxString val;
int braceCount = 1;
bool stopping = false;
if (line.length() >= 4000)
{
wxChar buf[100];
wxSnprintf(buf, sizeof(buf), _T("Sorry, value > 4000 chars in bib file at line %ld."), BibLine);
wxLogError(buf, "Tex2RTF Fatal Error");
return wxEmptyString;
}
while (!line.empty() && !stopping)
{
wxChar ch = line[0];
line = line.substr(1);
if (ch == _T('{'))
braceCount ++;
if (ch == _T('}'))
{
braceCount --;
if (braceCount == 0)
{
stopping = true;
break;
}
}
else if (quotesMayTerminate && ch == _T('"'))
{
stopping = true;
break;
}
if (!stopping)
{
if (!ignoreBraces || (ch != _T('{') && ch != _T('}')))
{
val << ch;
}
}
}
return val;
}
void BibReadValue(wxSTD istream& istr, wxChar *buffer, bool ignoreBraces = true,
bool quotesMayTerminate = true)
{
int braceCount = 1;
int i = 0;
buffer[i] = 0;
char ch = (char)istr.peek();
bool stopping = false;
while (!istr.eof() && !stopping)
{
// i ++;
if (i >= 4000)
int braceCount = 1;
int i = 0;
buffer[i] = 0;
char ch = (char)istr.peek();
bool stopping = false;
while (!istr.eof() && !stopping)
{
wxChar buf[100];
wxSnprintf(buf, sizeof(buf), _T("Sorry, value > 4000 chars in bib file at line %ld."), BibLine);
wxLogError(buf, "Tex2RTF Fatal Error");
return;
}
istr.get(ch);
// i ++;
if (i >= 4000)
{
wxChar buf[100];
wxSnprintf(buf, sizeof(buf), _T("Sorry, value > 4000 chars in bib file at line %ld."), BibLine);
wxLogError(buf, "Tex2RTF Fatal Error");
return;
}
istr.get(ch);
if (ch == '{')
braceCount ++;
if (ch == '{')
braceCount ++;
if (ch == '}')
{
braceCount --;
if (braceCount == 0)
{
stopping = true;
break;
}
if (ch == '}')
{
braceCount --;
if (braceCount == 0)
{
stopping = true;
break;
}
}
else if (quotesMayTerminate && ch == '"')
{
stopping = true;
break;
}
if (!stopping)
{
if (!ignoreBraces || (ch != '{' && ch != '}'))
{
buffer[i] = ch;
i ++;
}
}
if (ch == 10)
BibLine ++;
}
else if (quotesMayTerminate && ch == '"')
{
stopping = true;
break;
}
if (!stopping)
{
if (!ignoreBraces || (ch != '{' && ch != '}'))
{
buffer[i] = ch;
i ++;
}
}
if (ch == 10)
BibLine ++;
}
buffer[i] = 0;
wxUnusedVar(stopping);
buffer[i] = 0;
wxUnusedVar(stopping);
}
bool ReadBib(wxChar *filename)
@@ -1082,15 +1194,17 @@ TexRef *FindReference(wxChar *key)
*
*/
bool StringTobool(wxChar *val)
bool StringTobool(const wxString& val)
{
if (wxStrncmp(val, _T("yes"), 3) == 0 || wxStrncmp(val, _T("YES"), 3) == 0 ||
wxStrncmp(val, _T("on"), 2) == 0 || wxStrncmp(val, _T("ON"), 2) == 0 ||
wxStrncmp(val, _T("true"), 4) == 0 || wxStrncmp(val, _T("true"), 4) == 0 ||
wxStrncmp(val, _T("ok"), 2) == 0 || wxStrncmp(val, _T("OK"), 2) == 0 ||
wxStrncmp(val, _T("1"), 1) == 0)
return true;
else
wxString up(val);
up.MakeUpper();
if (up.IsSameAs(_T("YES")) ||
up.IsSameAs(_T("ON")) ||
up.IsSameAs(_T("OK")) |
up.IsSameAs(_T("1")))
return true;
return false;
}
@@ -1105,7 +1219,7 @@ void RegisterIntSetting (const wxString& s, int *number)
}
// Define a variable value from the .ini file
wxChar *RegisterSetting(wxChar *settingName, wxChar *settingValue, bool interactive)
wxChar *RegisterSetting(const wxString& settingName, const wxString& settingValue, bool interactive)
{
wxString settingValueStr( settingValue );
@@ -1351,7 +1465,7 @@ wxChar *RegisterSetting(wxChar *settingName, wxChar *settingValue, bool interact
else
{
wxChar buf[200];
wxSnprintf(buf, sizeof(buf), _T("Initialisation file error: unrecognised setting %s."), settingName);
wxSnprintf(buf, sizeof(buf), _T("Initialisation file error: unrecognised setting %s."), settingName.c_str());
if (interactive)
OnInform(buf);
wxStrcpy(errorCode, buf);
@@ -1359,87 +1473,81 @@ wxChar *RegisterSetting(wxChar *settingName, wxChar *settingValue, bool interact
return errorCode;
}
bool ReadCustomMacros(wxChar *filename)
bool ReadCustomMacros(const wxString& filename)
{
if (!wxFileExists(filename))
return false;
if (!wxFileExists(filename))
return false;
wxString name = filename;
wxSTD ifstream istr((char const *)name.fn_str(), wxSTD ios::in);
wxFileInputStream input( filename );
if(!input.Ok()) return false;
wxTextInputStream ini( input );
if (istr.bad()) return false;
CustomMacroList.Clear();
CustomMacroList.Clear();
char ch;
wxChar macroName[100];
wxChar macroBody[1000];
int noArgs;
while (!istr.eof())
{
BibEatWhiteSpace(istr);
istr.get(ch);
if (istr.eof())
break;
if (ch != '\\') // Not a macro definition, so must be NAME=VALUE
while (!input.Eof())
{
wxChar settingName[100];
settingName[0] = ch;
BibReadWord(istr, (settingName+1));
BibEatWhiteSpace(istr);
istr.get(ch);
if (ch != '=')
{
OnError(_T("Expected = following name: malformed tex2rtf.ini file."));
return false;
}
else
{
wxChar settingValue[200];
BibEatWhiteSpace(istr);
BibReadToEOL(istr, settingValue);
RegisterSetting(settingName, settingValue);
}
}
else
{
BibReadWord(istr, macroName);
BibEatWhiteSpace(istr);
istr.get(ch);
if (ch != '[')
{
OnError(_T("Expected [ followed by number of arguments: malformed tex2rtf.ini file."));
return false;
}
istr >> noArgs;
istr.get(ch);
if (ch != ']')
{
OnError(_T("Expected ] following number of arguments: malformed tex2rtf.ini file."));
return false;
}
BibEatWhiteSpace(istr);
istr.get(ch);
if (ch != '{')
{
OnError(_T("Expected { followed by macro body: malformed tex2rtf.ini file."));
return false;
}
CustomMacro *macro = new CustomMacro(macroName, noArgs, NULL);
BibReadValue(istr, macroBody, false, false); // Don't ignore extra braces
if (wxStrlen(macroBody) > 0)
macro->macroBody = copystring(macroBody);
wxString line = ini.ReadLine();
BibEatWhiteSpace(line);
if (line.empty()) continue;
if (line[0] != _T('\\')) // Not a macro definition, so must be NAME=VALUE
{
wxString settingName = BibReadWord(line);
BibEatWhiteSpace(line);
if (line.empty() || line[0] != _T('='))
{
OnError(_T("Expected = following name: malformed tex2rtf.ini file."));
return false;
}
else
{
line = line.substr(1);
BibEatWhiteSpace(line);
wxString settingValue = BibReadToEOL(line);
RegisterSetting(settingName, settingValue);
}
}
else
{
line = line.substr(1);
wxString macroName = BibReadWord(line);
BibEatWhiteSpace(line);
if (line[0] != _T('['))
{
OnError(_T("Expected [ followed by number of arguments: malformed tex2rtf.ini file."));
return false;
}
line = line.substr(1);
wxString noAargStr = line.BeforeFirst(_T(']'));
line = line.AfterFirst(_T(']'));
long noArgs;
if (!noAargStr.ToLong(&noArgs) || line.empty())
{
OnError(_T("Expected ] following number of arguments: malformed tex2rtf.ini file."));
return false;
}
BibEatWhiteSpace(line);
if (line[0] != _T('{'))
{
OnError(_T("Expected { followed by macro body: malformed tex2rtf.ini file."));
return false;
}
CustomMacro *macro = new CustomMacro(macroName.c_str(), noArgs, NULL);
wxString macroBody = BibReadValue(line, false, false); // Don't ignore extra braces
if (!macroBody.empty())
macro->macroBody = copystring(macroBody.c_str());
BibEatWhiteSpace(line);
CustomMacroList.Append(macroName.c_str(), macro);
AddMacroDef(ltCUSTOM_MACRO, macroName.c_str(), noArgs);
}
BibEatWhiteSpace(istr);
CustomMacroList.Append(macroName, macro);
AddMacroDef(ltCUSTOM_MACRO, macroName, noArgs);
}
}
wxChar mbuf[200];
wxSnprintf(mbuf, sizeof(mbuf), _T("Read initialization file %s."), filename);
OnInform(mbuf);
return true;
wxChar mbuf[200];
wxSnprintf(mbuf, sizeof(mbuf), _T("Read initialization file %s."), filename.c_str());
OnInform(mbuf);
return true;
}
CustomMacro *FindCustomMacro(wxChar *name)