29d22baf524d97b985dd5d7dc9db9b5de82e5d39
[scilab.git] / scilab / modules / history_manager / src / cpp / HistoryFile.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2007-2008 - INRIA - Allan CORNET
4 * Copyright (C) 2010-2011 - DIGITEO - Allan CORNET
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.1-en.txt
11 *
12 */
13 /*------------------------------------------------------------------------*/
14 #include <iostream>
15 #include <fstream>
16 #include <vector>
17 #include <string>
18 #include "HistoryFile.hxx"
19 /*------------------------------------------------------------------------*/
20 extern "C"
21 {
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25 #include <stdlib.h>
26 #include "sci_malloc.h"
27 #include "BOOL.h"
28 #include "sciprint.h"
29 #include "PATH_MAX.h"
30 #include "sci_home.h"
31 #include "machine.h"
32 #include "getCommentDateSession.h"
33 #include "scilabDefaults.h"
34 #include "charEncoding.h"
35 #include "mopen.h"
36 #include "mgetl.h"
37 #include "mclose.h"
38 #include "freeArrayOfString.h"
39 #include "os_wfopen.h"
40 #include "expandPathVariable.h"
41 };
42 /*------------------------------------------------------------------------*/
43 #define DEFAULT_HISTORY_FILE_MAX_LINES 20000
44 /*------------------------------------------------------------------------*/
45 HistoryFile::HistoryFile()
46 {
47     m_iMaxLines = DEFAULT_HISTORY_FILE_MAX_LINES;
48     m_stFilename.erase();
49 }
50 /*------------------------------------------------------------------------*/
51 HistoryFile::~HistoryFile()
52 {
53     reset();
54 }
55 /*------------------------------------------------------------------------*/
56 std::string HistoryFile::getFilename(void)
57 {
58     if (m_stFilename.empty())
59     {
60         setDefaultFilename();
61     }
62     return m_stFilename;
63 }
64 /*------------------------------------------------------------------------*/
65 void HistoryFile::setFilename(const std::string& _stFilename)
66 {
67     if (_stFilename.empty() == false)
68     {
69         // TODO: const_cast is very bad...
70         char * expanded = expandPathVariable((char *)(_stFilename.c_str()));
71         m_stFilename = std::string(expanded);
72         FREE(expanded);
73     }
74     else
75     {
76         setDefaultFilename();
77     }
78 }
79 /*------------------------------------------------------------------------*/
80 BOOL HistoryFile::setDefaultFilename(void)
81 {
82     BOOL bOK = FALSE;
83     char* SCIHOME = getSCIHOME();
84     std::string stDefaultFilename;
85
86     stDefaultFilename = std::string(SCIHOME);
87     stDefaultFilename += std::string(DIR_SEPARATOR);
88     stDefaultFilename += std::string(DEFAULT_HISTORY_FILE);
89
90     setFilename(stDefaultFilename);
91     FREE(SCIHOME);
92     return TRUE;
93 }
94 /*------------------------------------------------------------------------*/
95 BOOL HistoryFile::writeToFile(const std::string& _stFilename)
96 {
97     if (m_Commands.empty())
98     {
99         return FALSE;
100     }
101     else
102     {
103         std::ofstream fOut;
104
105         if (_stFilename.empty())
106         {
107             return FALSE;
108         }
109
110 #ifdef _MSC_VER
111         wchar_t* filename = to_wide_string(_stFilename.c_str());
112         fOut.open(filename, std::ios::trunc);
113         FREE(filename);
114 #else
115         fOut.open(_stFilename.c_str(), std::ios::trunc);
116 #endif
117         if (fOut.is_open() == false)
118         {
119             return FALSE;
120         }
121
122         for (auto &it : m_Commands)
123         {
124             fOut << it.c_str() << std::endl;
125         }
126         fOut.close();
127     }
128     return TRUE;
129 }
130 /*------------------------------------------------------------------------*/
131 BOOL HistoryFile::writeToFile(void)
132 {
133     if (m_stFilename.empty() == false)
134     {
135         return writeToFile(m_stFilename);
136     }
137     return FALSE;
138 }
139 /*------------------------------------------------------------------------*/
140
141 errorLoadHistoryCode HistoryFile::loadFromFile(const std::string& _stFilename)
142 {
143     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
144     std::ifstream fIn;
145     std::vector<std::string> vstLines;
146
147     fIn.open(_stFilename.c_str());
148     if (fIn.is_open() == false)
149     {
150         return returnedError;
151     }
152
153     //read entire file and store it in vstLines.
154     while (fIn.eof() == false)
155     {
156         std::string stLine;
157         std::getline(fIn, stLine);
158
159         if (stLine.empty())
160         {
161             continue;
162         }
163         vstLines.push_back(stLine);
164     }
165     fIn.close();
166
167     //fill history list
168     int iStart = 0;
169     int iEnd = (int)vstLines.size();
170     returnedError = NO_ERROR_HISTORY_LOADED;
171
172     if (vstLines.size() > getDefaultMaxNbLines())
173     {
174         iStart = (int)vstLines.size() - getDefaultMaxNbLines();
175         returnedError = HISTORY_TRUNCATED;
176     }
177
178     for (int i = iStart ; i < iEnd ; i++)
179     {
180         m_Commands.push_back(vstLines[i]);
181     }
182
183     return returnedError;
184
185     /*
186         int fd = 0;
187         int f_swap = 0;
188         double res = 0.0;
189         int errMOPEN = MOPEN_INVALID_STATUS;
190         double dErrClose = 0.;
191
192         C2F(mopen)(&fd, (char*)filename.c_str(), "rt", &f_swap, &res, &errMOPEN);
193         if (errMOPEN == MOPEN_NO_ERROR)
194         {
195
196             int errMGETL = MGETL_ERROR;
197             int nblines = 0;
198             char **lines = mgetl(fd, -1, &nblines, &errMGETL);
199
200             C2F(mclose)(&fd, &dErrClose);
201             if (errMGETL == MGETL_NO_ERROR)
202             {
203                 if (lines)
204                 {
205                     int iStart = 0;
206                     int iEnd = 0;
207                     if (nblines > getDefaultMaxNbLines())
208                     {
209                         iStart = nblines - getDefaultMaxNbLines();
210                         returnedError = HISTORY_TRUNCATED;
211                     }
212                     else
213                     {
214                         iStart = 0;
215                         returnedError = NO_ERROR_HISTORY_LOADED;
216                     }
217                     iEnd = nblines;
218
219                     for (int i = iStart; i < iEnd; i++)
220                     {
221                         CommandLine Line(lines[i]);
222                         Commands.push_back(Line);
223                     }
224                     freeArrayOfString(lines, nblines);
225                     lines = NULL;
226                 }
227             }
228         }
229         return returnedError;
230     */
231 }
232 /*------------------------------------------------------------------------*/
233 errorLoadHistoryCode HistoryFile::loadFromFile(void)
234 {
235     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
236     if (m_stFilename.empty() == false)
237     {
238         returnedError = loadFromFile(m_stFilename);
239     }
240     return returnedError;
241 }
242 /*------------------------------------------------------------------------*/
243 std::list<std::string> HistoryFile::getHistory(void)
244 {
245     return m_Commands;
246 }
247 /*------------------------------------------------------------------------*/
248 BOOL HistoryFile::setHistory(const std::list<std::string>& _lstCommands)
249 {
250     BOOL bOK = FALSE;
251
252     if (m_Commands.empty() == false)
253     {
254         m_Commands.clear();
255     }
256
257     for (auto& it : _lstCommands)
258     {
259         m_Commands.push_back(it);
260     }
261     return bOK;
262 }
263 /*------------------------------------------------------------------------*/
264 BOOL HistoryFile::reset(void)
265 {
266     m_Commands.clear();
267     m_stFilename.erase();
268     return TRUE;
269 }
270 /*------------------------------------------------------------------------*/
271 int HistoryFile::getDefaultMaxNbLines(void)
272 {
273     return m_iMaxLines;
274 }
275 /*------------------------------------------------------------------------*/
276 BOOL HistoryFile::setDefaultMaxNbLines(int _iMaxLines)
277 {
278     BOOL bOK = FALSE;
279     if (_iMaxLines > 0)
280     {
281         m_iMaxLines = _iMaxLines;
282         bOK = TRUE;
283     }
284     return bOK;
285 }
286 /*------------------------------------------------------------------------*/