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