History: restore it
[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(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(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         std::list<std::string>::const_iterator it;
123         for (it = m_Commands.begin(); it != m_Commands.end(); it++)
124         {
125             fOut << (*it).c_str() << std::endl;
126         }
127         fOut.close();
128     }
129     return TRUE;
130 }
131 /*------------------------------------------------------------------------*/
132 BOOL HistoryFile::writeToFile(void)
133 {
134     if (m_stFilename.empty() == false)
135     {
136         return writeToFile(m_stFilename);
137     }
138     return FALSE;
139 }
140 /*------------------------------------------------------------------------*/
141
142 errorLoadHistoryCode HistoryFile::loadFromFile(std::string _stFilename)
143 {
144     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
145     std::ifstream fIn;
146     std::vector<std::string> vstLines;
147
148     fIn.open(_stFilename.c_str());
149     if (fIn.is_open() == false)
150     {
151         return returnedError;
152     }
153
154     //read entire file and store it in vstLines.
155     while (fIn.eof() == false)
156     {
157         std::string stLine;
158         std::getline(fIn, stLine);
159
160         if (stLine.empty())
161         {
162             continue;
163         }
164         vstLines.push_back(stLine);
165     }
166     fIn.close();
167
168     //fill history list
169     int iStart = 0;
170     int iEnd = (int)vstLines.size();
171     returnedError = NO_ERROR_HISTORY_LOADED;
172
173     if (vstLines.size() > getDefaultMaxNbLines())
174     {
175         iStart = (int)vstLines.size() - getDefaultMaxNbLines();
176         returnedError = HISTORY_TRUNCATED;
177     }
178
179     for (int i = iStart ; i < iEnd ; i++)
180     {
181         m_Commands.push_back(vstLines[i]);
182     }
183
184     return returnedError;
185
186     /*
187         int fd = 0;
188         int f_swap = 0;
189         double res = 0.0;
190         int errMOPEN = MOPEN_INVALID_STATUS;
191         double dErrClose = 0.;
192
193         C2F(mopen)(&fd, (char*)filename.c_str(), "rt", &f_swap, &res, &errMOPEN);
194         if (errMOPEN == MOPEN_NO_ERROR)
195         {
196
197             int errMGETL = MGETL_ERROR;
198             int nblines = 0;
199             char **lines = mgetl(fd, -1, &nblines, &errMGETL);
200
201             C2F(mclose)(&fd, &dErrClose);
202             if (errMGETL == MGETL_NO_ERROR)
203             {
204                 if (lines)
205                 {
206                     int iStart = 0;
207                     int iEnd = 0;
208                     if (nblines > getDefaultMaxNbLines())
209                     {
210                         iStart = nblines - getDefaultMaxNbLines();
211                         returnedError = HISTORY_TRUNCATED;
212                     }
213                     else
214                     {
215                         iStart = 0;
216                         returnedError = NO_ERROR_HISTORY_LOADED;
217                     }
218                     iEnd = nblines;
219
220                     for (int i = iStart; i < iEnd; i++)
221                     {
222                         CommandLine Line(lines[i]);
223                         Commands.push_back(Line);
224                     }
225                     freeArrayOfString(lines, nblines);
226                     lines = NULL;
227                 }
228             }
229         }
230         return returnedError;
231     */
232 }
233 /*------------------------------------------------------------------------*/
234 errorLoadHistoryCode HistoryFile::loadFromFile(void)
235 {
236     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
237     if (m_stFilename.empty() == false)
238     {
239         returnedError = loadFromFile(m_stFilename);
240     }
241     return returnedError;
242 }
243 /*------------------------------------------------------------------------*/
244 std::list<std::string> HistoryFile::getHistory(void)
245 {
246     return m_Commands;
247 }
248 /*------------------------------------------------------------------------*/
249 BOOL HistoryFile::setHistory(std::list<std::string> _lstCommands)
250 {
251     BOOL bOK = FALSE;
252     std::list<std::string>::const_iterator it;
253
254     if (m_Commands.empty() == false)
255     {
256         m_Commands.clear();
257     }
258
259     for (it = _lstCommands.begin(); it != _lstCommands.end(); it++)
260     {
261         m_Commands.push_back(*it);
262     }
263     return bOK;
264 }
265 /*------------------------------------------------------------------------*/
266 BOOL HistoryFile::reset(void)
267 {
268     m_Commands.clear();
269     m_stFilename.erase();
270     return TRUE;
271 }
272 /*------------------------------------------------------------------------*/
273 int HistoryFile::getDefaultMaxNbLines(void)
274 {
275     return m_iMaxLines;
276 }
277 /*------------------------------------------------------------------------*/
278 BOOL HistoryFile::setDefaultMaxNbLines(int _iMaxLines)
279 {
280     BOOL bOK = FALSE;
281     if (_iMaxLines > 0)
282     {
283         m_iMaxLines = _iMaxLines;
284         bOK = TRUE;
285     }
286     return bOK;
287 }
288 /*------------------------------------------------------------------------*/