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