2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2008 - INRIA - Bruno JOFRET
4 * Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
22 #include "parser_private.hxx"
26 #include "charEncoding.h"
27 #include "sci_malloc.h"
32 #include "sci_tmpdir.h"
34 #include "localization.h"
35 #include "os_string.h"
39 #include "os_wfopen.h"
45 extern int yylex_destroy();
47 void Parser::cleanup()
52 void Parser::parseFile(const std::wstring& fileName, const std::wstring& progName)
54 // Calling Parse state machine in C with global values
55 // Must be locked to avoid concurrent access
57 if (getParseTrace() == true)
59 ParserSingleInstance::enableParseTrace();
63 ParserSingleInstance::disableParseTrace();
68 ParserSingleInstance::parseFile(fileName, progName);
70 catch (const ast::InternalError& ie)
72 ParserSingleInstance::setTree(nullptr);
73 ParserSingleInstance::setExitStatus(Parser::Failed);
76 this->setExitStatus(ParserSingleInstance::getExitStatus());
77 this->setControlStatus(ParserSingleInstance::getControlStatus());
78 if (getExitStatus() == Parser::Succeded)
80 this->setTree(ParserSingleInstance::getTree());
84 this->setErrorMessage(ParserSingleInstance::getErrorMessage());
87 if (getExitStatus() != Parser::Succeded)
89 delete ParserSingleInstance::getTree();
90 ParserSingleInstance::setTree(nullptr);
97 /** \brief parse the given file name */
98 void ParserSingleInstance::parseFile(const std::wstring& fileName, const std::wstring& progName)
100 yylloc.first_line = yylloc.last_line = 1;
101 yylloc.first_column = yylloc.last_column = 1;
103 yyin = os_wfopen(fileName.c_str(), L"r");
105 char* pstTemp = wide_string_to_UTF8(fileName.c_str());
106 yyin = fopen(pstTemp, "r");
112 wchar_t szError[bsiz];
113 os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", fileName.c_str());
114 throw ast::InternalError(szError);
118 ParserSingleInstance::disableStrictMode();
119 // Parser::getInstance()->enableStrictMode();
120 ParserSingleInstance::setFileName(fileName);
121 ParserSingleInstance::setProgName(progName);
123 ParserSingleInstance::setTree(nullptr);
124 ParserSingleInstance::setExitStatus(Parser::Succeded);
125 ParserSingleInstance::resetControlStatus();
126 ParserSingleInstance::resetErrorMessage();
131 void Parser::parse(const char *command)
133 // Calling Parse state machine in C with global values
134 // Must be locked to avoid concurrent access
136 if (getParseTrace() == true)
138 ParserSingleInstance::enableParseTrace();
142 ParserSingleInstance::disableParseTrace();
145 ParserSingleInstance::parse(command);
146 this->setExitStatus(ParserSingleInstance::getExitStatus());
147 this->setControlStatus(ParserSingleInstance::getControlStatus());
148 if (getExitStatus() == Parser::Succeded)
150 this->setTree(ParserSingleInstance::getTree());
154 this->setErrorMessage(ParserSingleInstance::getErrorMessage());
157 if (getControlStatus() == AllControlClosed && get_last_token() != YYEOF)
159 //set parser last token to EOF
163 if (getExitStatus() != Parser::Succeded)
165 delete ParserSingleInstance::getTree();
166 ParserSingleInstance::setTree(nullptr);
172 void Parser::parse(const wchar_t *command)
174 char* pstCommand = wide_string_to_UTF8(command);
179 bool Parser::stopOnFirstError(void)
181 return ParserSingleInstance::stopOnFirstError();
183 void Parser::enableStopOnFirstError(void)
185 ParserSingleInstance::enableStopOnFirstError();
187 void Parser::disableStopOnFirstError(void)
189 ParserSingleInstance::disableStopOnFirstError();
192 /** \brief parse the given file command */
193 void ParserSingleInstance::parse(const char *command)
195 size_t len = strlen(command);
197 yylloc.first_line = yylloc.last_line = 1;
198 yylloc.first_column = yylloc.last_column = 1;
200 char szFile[MAX_PATH];
201 char* pstTmpDIr = getTMPDIR();
202 os_sprintf(szFile, "%s\\%s", pstTmpDIr, "command.temp");
207 fileLocker = nullptr;
211 err = fopen_s(&yyin, szFile, "w");
214 ParserSingleInstance::setExitStatus(Parser::Failed);
215 ParserSingleInstance::resetErrorMessage();
216 wchar_t szError[bsiz];
217 wchar_t* wszFile = to_wide_string(szFile);
218 os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", wszFile);
220 appendErrorMessage(szError);
224 fwrite(command, sizeof(char), len, yyin);
226 fopen_s(&yyin, szFile, "r");
230 char szFile[PATH_MAX];
231 char* pstTmpDIr = "/tmp";
232 sprintf(szFile, "%s/%s", getTMPDIR(), "command.temp");
237 fileLocker = nullptr;
239 yyin = fopen(szFile, "w");
240 fwrite(command, 1, len, yyin);
242 yyin = fopen(szFile, "r");
248 yyin = fmemopen((void*)command, len, "r");
252 ParserSingleInstance::disableStrictMode();
253 ParserSingleInstance::setFileName(L"prompt");
254 ParserSingleInstance::setTree(nullptr);
255 ParserSingleInstance::setExitStatus(Parser::Succeded);
256 ParserSingleInstance::resetControlStatus();
257 ParserSingleInstance::resetErrorMessage();
267 //reopen a file to prevents max file opened.
268 fopen_s(&fileLocker, szFile, "w");
271 fileLocker = fopen(szFile, "w");
275 /** \brief put the asked line in codeLine */
276 char *ParserSingleInstance::getCodeLine(int line, char **codeLine)
282 ** WARNING : *codeLine will be allocated by getline
283 ** so it must be manually freed !
285 for (i = 1 ; i <= line ; ++i)
287 fgets(*codeLine, 4096, yyin);
292 std::wstring& ParserSingleInstance::getErrorMessage(void)
294 return _error_message;
297 void ParserSingleInstance::appendErrorMessage(const std::wstring& message)
299 if (ParserSingleInstance::stopOnFirstError() && _error_message.empty() == false)
304 _error_message += message;
307 /** \brief enable Bison trace mode */
308 void ParserSingleInstance::enableParseTrace(void)
313 /** \brief disable Bison trace mode */
314 void ParserSingleInstance::disableParseTrace(void)
319 void Parser::releaseTmpFile()
321 ParserSingleInstance::releaseTmpFile();
324 void ParserSingleInstance::releaseTmpFile()
328 //fclose(fileLocker);
329 //fileLocker = nullptr;
333 std::wstring ParserSingleInstance::_file_name;
334 std::wstring ParserSingleInstance::_prog_name;
335 std::wstring ParserSingleInstance::_error_message;
336 bool ParserSingleInstance::_strict_mode = false;
337 bool ParserSingleInstance::_stop_on_first_error = true;
338 ast::Exp* ParserSingleInstance::_the_program = nullptr;
339 Parser::ParserStatus ParserSingleInstance::_exit_status = Parser::Succeded;
340 std::list<Parser::ControlStatus> ParserSingleInstance::_control_status;
341 FILE* ParserSingleInstance::fileLocker = nullptr;