Threads execution managemement.
[scilab.git] / scilab / modules / ast / src / cpp / parse / parser.cpp
1 /*
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
5  *
6  *  This file must be used under the terms of the CeCILL.
7  *  This source file is licensed as described in the file COPYING, which
8  *  you should have received as part of this distribution.  The terms
9  *  are also available at
10  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 #include <fstream>
15 #include <string>
16 #include <string.h>
17 #include "parser.hxx"
18 #include "parser_private.hxx"
19 #include "scilabexception.hxx"
20
21 #ifdef _MSC_VER
22 #include "windows.h"
23 #include "charEncoding.h"
24 #include "sci_malloc.h"
25 #endif
26
27 extern "C"
28 {
29 #include "sci_tmpdir.h"
30 #include "Scierror.h"
31 #include "localization.h"
32 #include "os_string.h"
33 #ifdef __APPLE__
34 #include "PATH_MAX.h"
35 #endif
36 }
37
38 extern FILE*    yyin;
39 extern int      yyparse();
40 extern int      yydebug;
41 extern int      yylex_destroy();
42
43 void Parser::cleanup()
44 {
45     yylex_destroy();
46 }
47
48 void Parser::parseFile(const std::wstring& fileName, const std::wstring& progName)
49 {
50     // Calling Parse state machine in C with global values
51     // Must be locked to avoid concurrent access
52     // FIXME : LOCK
53     if (getParseTrace() == true)
54     {
55         ParserSingleInstance::enableParseTrace();
56     }
57     else
58     {
59         ParserSingleInstance::disableParseTrace();
60     }
61     ParserSingleInstance::parseFile(fileName, progName);
62     this->setExitStatus(ParserSingleInstance::getExitStatus());
63     this->setControlStatus(ParserSingleInstance::getControlStatus());
64     if (getExitStatus() == Parser::Succeded)
65     {
66         this->setTree(ParserSingleInstance::getTree());
67     }
68     else
69     {
70         this->setErrorMessage(ParserSingleInstance::getErrorMessage());
71     }
72     // FIXME : UNLOCK
73 }
74
75
76 /** \brief parse the given file name */
77 void ParserSingleInstance::parseFile(const std::wstring& fileName, const std::wstring& progName)
78 {
79     yylloc.first_line = yylloc.last_line = 1;
80     yylloc.first_column = yylloc.last_column = 1;
81 #ifdef _MSC_VER
82     _wfopen_s(&yyin, fileName.c_str(), L"r");
83 #else
84     char* pstTemp = wide_string_to_UTF8(fileName.c_str());
85     yyin = fopen(pstTemp, "r");
86     FREE(pstTemp);
87 #endif
88
89     if (!yyin)
90     {
91         wchar_t szError[bsiz];
92         os_swprintf(szError, bsiz, _W("%ls: Cannot open file %ls.\n").c_str(), L"parser", fileName.c_str());
93         throw ast::ScilabError(szError, 999, *new Location());
94     }
95
96
97     ParserSingleInstance::disableStrictMode();
98     //  Parser::getInstance()->enableStrictMode();
99     ParserSingleInstance::setFileName(fileName);
100     ParserSingleInstance::setProgName(progName);
101
102     ParserSingleInstance::setExitStatus(Parser::Succeded);
103     ParserSingleInstance::resetControlStatus();
104     ParserSingleInstance::resetErrorMessage();
105     yyparse();
106     fclose(yyin);
107 }
108
109 void Parser::parse(char *command)
110 {
111     // Calling Parse state machine in C with global values
112     // Must be locked to avoid concurrent access
113     // FIXME : LOCK
114     if (getParseTrace() == true)
115     {
116         ParserSingleInstance::enableParseTrace();
117     }
118     else
119     {
120         ParserSingleInstance::disableParseTrace();
121     }
122
123     ParserSingleInstance::parse(command);
124     this->setExitStatus(ParserSingleInstance::getExitStatus());
125     this->setControlStatus(ParserSingleInstance::getControlStatus());
126     if (getExitStatus() == Parser::Succeded)
127     {
128         this->setTree(ParserSingleInstance::getTree());
129     }
130     else
131     {
132         this->setErrorMessage(ParserSingleInstance::getErrorMessage());
133     }
134
135     if (getControlStatus() == AllControlClosed && get_last_token() != YYEOF)
136     {
137         //set parser last token to EOF
138         scan_throw(YYEOF);
139     }
140
141     // FIXME : UNLOCK
142 }
143
144 void Parser::parse(wchar_t *command)
145 {
146     char* pstCommand = wide_string_to_UTF8(command);
147     parse(pstCommand);
148     FREE(pstCommand);
149 }
150
151 /** \brief parse the given file command */
152 void ParserSingleInstance::parse(char *command)
153 {
154     size_t len = strlen(command);
155
156     yylloc.first_line = yylloc.last_line = 1;
157     yylloc.first_column = yylloc.last_column = 1;
158 #ifdef _MSC_VER
159     char szFile[MAX_PATH];
160     char* pstTmpDIr = getTMPDIR();
161     os_sprintf(szFile, "%s\\%s", pstTmpDIr, "command.temp");
162     FREE(pstTmpDIr);
163     if (fileLocker)
164     {
165         fclose(fileLocker);
166     }
167
168     fopen_s(&yyin, szFile, "w");
169     fwrite(command, sizeof(char), len, yyin);
170     fclose(yyin);
171     fopen_s(&yyin, szFile, "r");
172 #endif
173
174 #ifdef __APPLE__
175     char szFile[PATH_MAX];
176     char* pstTmpDIr = "/tmp";
177     sprintf(szFile, "%s/%s", getTMPDIR(), "command.temp");
178     //FREE(pstTmpDIr);
179     if (fileLocker)
180     {
181         fclose(fileLocker);
182     }
183     yyin = fopen(szFile, "w");
184     fwrite(command, 1, len, yyin);
185     fclose(yyin);
186     yyin = fopen(szFile, "r");
187 #endif
188
189
190 #ifndef _MSC_VER
191 #ifndef __APPLE__
192     yyin = fmemopen(command, len, "r");
193 #endif
194 #endif
195
196     ParserSingleInstance::disableStrictMode();
197     ParserSingleInstance::setFileName(L"prompt");
198     ParserSingleInstance::setExitStatus(Parser::Succeded);
199     ParserSingleInstance::resetControlStatus();
200     ParserSingleInstance::resetErrorMessage();
201
202     yyparse();
203
204     fclose(yyin);
205 #ifdef _MSC_VER
206     DeleteFileA(szFile);
207 #endif
208
209 #ifdef _MSC_VER
210     //reopen a file to prevents max file opened.
211     fopen_s(&fileLocker, szFile, "w");
212 #endif
213 #ifdef __APPLE__
214     fileLocker = fopen(szFile, "w");
215 #endif
216 }
217
218 /** \brief put the asked line in codeLine */
219 char *ParserSingleInstance::getCodeLine(int line, char **codeLine)
220 {
221     int i = 0;
222
223     rewind(yyin);
224     /*
225     ** WARNING : *codeLine will be allocated by getline
226     ** so it must be manually freed !
227     */
228     for (i = 1 ; i <= line ; ++i)
229     {
230         fgets(*codeLine, 4096, yyin);
231     }
232     return *codeLine;
233 }
234
235 std::wstring& ParserSingleInstance::getErrorMessage(void)
236 {
237     return _error_message;
238 }
239
240 void ParserSingleInstance::appendErrorMessage(std::wstring message)
241 {
242     _error_message += message;
243 }
244
245 /** \brief enable Bison trace mode */
246 void ParserSingleInstance::enableParseTrace(void)
247 {
248     yydebug = 1;
249 }
250
251 /** \brief disable Bison trace mode */
252 void ParserSingleInstance::disableParseTrace(void)
253 {
254     yydebug = 0;
255 }
256
257 std::wstring ParserSingleInstance::_file_name;
258 std::wstring ParserSingleInstance::_prog_name;
259 std::wstring ParserSingleInstance::_error_message;
260 bool ParserSingleInstance::_strict_mode = false;
261 bool ParserSingleInstance::_stop_on_first_error = false;
262 ast::Exp* ParserSingleInstance::_the_program = NULL;
263 Parser::ParserStatus ParserSingleInstance::_exit_status = Parser::Succeded;
264 std::list<Parser::ControlStatus> ParserSingleInstance::_control_status;
265 FILE* ParserSingleInstance::fileLocker = NULL;
266