Commit ec2da042 by Christophe Geuzaine

new string macros, allowing define macros explicitly - and use them without a…

new string macros, allowing define macros explicitly - and use them without a file context (e.g. in Parse commands)
parent fd907ab5
......@@ -9,6 +9,8 @@
#include <string>
#include "MacroManager.h"
extern std::string getdp_yystring;
class File_Position
{
public:
......@@ -27,42 +29,44 @@ class mystack
class mymap
{
public:
std::map<std::string, File_Position> m;
std::map<std::string, File_Position> inFile;
std::map<std::string, std::string> inString;
};
MacroManager *MacroManager::instance = 0;
MacroManager *MacroManager::_instance = 0;
MacroManager::MacroManager()
{
macros = new mymap;
calls = new mystack;
_macros = new mymap;
_calls = new mystack;
}
MacroManager *MacroManager::Instance()
{
if(!instance) {
instance = new MacroManager;
if(!_instance) {
_instance = new MacroManager;
}
return instance;
return _instance;
}
void MacroManager::clear()
{
macros->m.clear();
_macros->inFile.clear();
_macros->inString.clear();
}
int MacroManager::enterMacro(const std::string &name, FILE **f,
std::string &filename, long int &lno) const
{
if(macros->m.find(name) == macros->m.end())
if(_macros->inFile.find(name) == _macros->inFile.end())
return 0;
File_Position fpold;
fpold.lineno = lno;
fpold.filename = filename;
fpold.file = *f;
fgetpos(fpold.file, &fpold.position);
calls->s.push(fpold);
File_Position fp = (macros->m)[name];
_calls->s.push(fpold);
File_Position fp = (_macros->inFile)[name];
fsetpos(fp.file, &fp.position);
*f = fp.file;
filename = fp.filename;
......@@ -72,30 +76,47 @@ int MacroManager::enterMacro(const std::string &name, FILE **f,
int MacroManager::leaveMacro(FILE **f, std::string &filename, long int &lno)
{
if(!calls->s.size())
if(!_calls->s.size())
return 0;
File_Position fp;
fp = calls->s.top();
calls->s.pop();
fp = _calls->s.top();
_calls->s.pop();
fsetpos(fp.file, &fp.position);
*f = fp.file;
filename = fp.filename;
// lno = fp.lineno;
// To fix: bad line number after leaving macro if not -1
lno = fp.lineno-1;
lno = fp.lineno - 1;
return 1;
}
int MacroManager::createMacro(const std::string &name, FILE *f,
const std::string &filename, long int lno)
{
if(macros->m.find(name) != macros->m.end())
if(_macros->inFile.find(name) != _macros->inFile.end())
return 0;
File_Position fp;
fp.file = f;
fp.filename = filename;
fp.lineno = lno;
fgetpos(fp.file, &fp.position);
(macros->m)[name] = fp;
(_macros->inFile)[name] = fp;
return 1;
}
int MacroManager::createStringMacro(const std::string &name,
const std::string &value)
{
if(_macros->inString.find(name) != _macros->inString.end())
return 0;
(_macros->inString)[name] = value;
return 1;
}
int MacroManager::enterStringMacro(const std::string &name) const
{
if(_macros->inString.find(name) == _macros->inString.end())
return 0;
getdp_yystring = (_macros->inString)[name];
return 1;
}
......@@ -15,18 +15,24 @@ class mymap;
class MacroManager
{
mymap *macros;
mystack *calls;
MacroManager ();
static MacroManager *instance;
private:
mymap *_macros;
mystack *_calls;
MacroManager();
static MacroManager *_instance;
public :
static MacroManager* Instance();
static MacroManager *Instance();
void clear();
// macro in a file that is (being) parsed
int createMacro(const std::string &name, FILE *f,
const std::string &filename, long int lineno);
int leaveMacro(FILE **f, std::string &filename, long int &lineno);
int enterMacro(const std::string &name, FILE **f,
std::string &filename, long int &lineno) const;
int leaveMacro(FILE **f, std::string &filename, long int &lineno);
// explicit macro as a string
int createStringMacro(const std::string &name, const std::string &value);
int enterStringMacro(const std::string &name) const;
};
#endif
......@@ -315,6 +315,14 @@ std::string Fix_RelativePath(const char *name, const char *reference)
}
}
#if !defined(HAVE_NX)
void Read_ProblemPreamble()
{
// no-op ; could be used to fill getdp_yystring in order to parse some
// definitions before the actuel .pro file processing starts.
}
#endif
static std::vector<FILE*> openFiles;
void Read_ProblemStructure(const char *name)
......
......@@ -1734,6 +1734,7 @@ int fcmp_PostQuantity_Name (const void *a, const void *b);
int fcmp_PostOperation_Name (const void *a, const void *b);
void Init_ProblemStructure();
void Read_ProblemPreamble();
void Read_ProblemStructure(const char *fileName);
void Finalize_ProblemStructure();
void Print_ProblemStructure();
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7834,19 +7834,31 @@ Loop :
(&getdp_yyin, getdp_yyname, getdp_yylinenum))
vyyerror(0, "Error while exiting macro");
}
| tMacro LP CharExpr ',' CharExpr RP tEND
{
if(!MacroManager::Instance()->createStringMacro($3, $5))
vyyerror(0, "Redefinition of macro '%s'", $2);
Free($3);
Free($5);
}
| tCall CallArg tEND
{
if(!MacroManager::Instance()->enterMacro
(std::string($2), &getdp_yyin, getdp_yyname, getdp_yylinenum))
vyyerror(0, "Unknown macro '%s'", $2);
(std::string($2), &getdp_yyin, getdp_yyname, getdp_yylinenum)){
if(!MacroManager::Instance()->enterStringMacro(std::string($2)))
vyyerror(0, "Unknown macro '%s'", $2);
}
Free($2);
}
| tCallTest '(' FExpr ')' CallArg tEND
{
if($3)
if($3){
if(!MacroManager::Instance()->enterMacro
(std::string($5), &getdp_yyin, getdp_yyname, getdp_yylinenum))
vyyerror(0, "Unknown macro '%s'", $5);
(std::string($5), &getdp_yyin, getdp_yyname, getdp_yylinenum)){
if(!MacroManager::Instance()->enterStringMacro(std::string($5)))
vyyerror(0, "Unknown macro '%s'", $5);
}
}
Free($5);
}
| tIf '(' FExpr ')'
......
......@@ -672,6 +672,7 @@ int MainKernel(int argc, char *argv[])
LinAlg_InitializeSolver(&sargc, &sargv);
Init_ProblemStructure();
Read_ProblemPreamble();
Read_ProblemStructure(pro);
Finalize_ProblemStructure();
......
......@@ -1880,14 +1880,18 @@ Macros are defined as follows:
@ftable @code
@item Macro @var{string} | @var{expression-char}
Begins the declaration of a user-defined macro named @var{string}. The
body of the macro starts on the line after `@code{Macro
@var{string}}', and can contain any GetDP command.
Begins the declaration of a user-defined file macro named
@var{string}. The body of the macro starts on the line after
`@code{Macro @var{string}}', and can contain any GetDP command.
@item Return
Ends the body of the current user-defined macro. Macro declarations
Ends the body of the current user-defined file macro. Macro declarations
cannot be imbricated, and must be made outside any GetDP object.
@item Macro ( @var{expression-char} , @var{expression-char} ) ;
Begins the declaration of a user-defined string macro. The body of the
macro is given explicitly as the second argument.
@end ftable
Macros, loops and conditionals can be used in any of the following
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment