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 /** \brief parse the given file command */
180 void ParserSingleInstance::parse(const char *command)
182 size_t len = strlen(command);
184 yylloc.first_line = yylloc.last_line = 1;
185 yylloc.first_column = yylloc.last_column = 1;
187 char szFile[MAX_PATH];
188 char* pstTmpDIr = getTMPDIR();
189 os_sprintf(szFile, "%s\\%s", pstTmpDIr, "command.temp");
194 fileLocker = nullptr;
198 err = fopen_s(&yyin, szFile, "w");
201 ParserSingleInstance::setExitStatus(Parser::Failed);
202 ParserSingleInstance::resetErrorMessage();
203 wchar_t szError[bsiz];
204 wchar_t* wszFile = to_wide_string(szFile);
205 os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", wszFile);
207 appendErrorMessage(szError);
211 fwrite(command, sizeof(char), len, yyin);
213 fopen_s(&yyin, szFile, "r");
217 char szFile[PATH_MAX];
218 char* pstTmpDIr = "/tmp";
219 sprintf(szFile, "%s/%s", getTMPDIR(), "command.temp");
224 fileLocker = nullptr;
226 yyin = fopen(szFile, "w");
227 fwrite(command, 1, len, yyin);
229 yyin = fopen(szFile, "r");
235 yyin = fmemopen((void*)command, len, "r");
239 ParserSingleInstance::disableStrictMode();
240 ParserSingleInstance::setFileName(L"prompt");
241 ParserSingleInstance::setTree(nullptr);
242 ParserSingleInstance::setExitStatus(Parser::Succeded);
243 ParserSingleInstance::resetControlStatus();
244 ParserSingleInstance::resetErrorMessage();
254 //reopen a file to prevents max file opened.
255 fopen_s(&fileLocker, szFile, "w");
258 fileLocker = fopen(szFile, "w");
262 /** \brief put the asked line in codeLine */
263 char *ParserSingleInstance::getCodeLine(int line, char **codeLine)
269 ** WARNING : *codeLine will be allocated by getline
270 ** so it must be manually freed !
272 for (i = 1 ; i <= line ; ++i)
274 fgets(*codeLine, 4096, yyin);
279 std::wstring& ParserSingleInstance::getErrorMessage(void)
281 return _error_message;
284 void ParserSingleInstance::appendErrorMessage(const std::wstring& message)
286 _error_message += message;
289 /** \brief enable Bison trace mode */
290 void ParserSingleInstance::enableParseTrace(void)
295 /** \brief disable Bison trace mode */
296 void ParserSingleInstance::disableParseTrace(void)
301 void Parser::releaseTmpFile()
303 ParserSingleInstance::releaseTmpFile();
306 void ParserSingleInstance::releaseTmpFile()
310 //fclose(fileLocker);
311 //fileLocker = nullptr;
315 std::wstring ParserSingleInstance::_file_name;
316 std::wstring ParserSingleInstance::_prog_name;
317 std::wstring ParserSingleInstance::_error_message;
318 bool ParserSingleInstance::_strict_mode = false;
319 bool ParserSingleInstance::_stop_on_first_error = false;
320 ast::Exp* ParserSingleInstance::_the_program = nullptr;
321 Parser::ParserStatus ParserSingleInstance::_exit_status = Parser::Succeded;
322 std::list<Parser::ControlStatus> ParserSingleInstance::_control_status;
323 FILE* ParserSingleInstance::fileLocker = nullptr;