* Bug #12333 fixed - Cleaned command history is restored after reopening Scilab.
[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-en.txt
11 *
12 */
13 /*------------------------------------------------------------------------*/
14 #include "HistoryFile.hxx"
15 #include "MALLOC.h"
16 #include "BOOL.h"
17 /*------------------------------------------------------------------------*/
18 extern "C"
19 {
20 #include <stdio.h>
21 #include <string.h>
22 #include <time.h>
23 #include <stdlib.h>
24 #include "sciprint.h"
25 #include "PATH_MAX.h"
26 #include "SCIHOME.h"
27 #include "machine.h"
28 #include "getCommentDateSession.h"
29 #include "scilabDefaults.h"
30 #include "charEncoding.h"
31 #include "mopen.h"
32 #include "mgetl.h"
33 #include "mclose.h"
34 #include "freeArrayOfString.h"
35 #include "getScilabPreference.h"
36 #include "expandPathVariable.h"
37 };
38 /*------------------------------------------------------------------------*/
39 #define DEFAULT_HISTORY_FILE_MAX_LINES 20000
40 /*------------------------------------------------------------------------*/
41 HistoryFile::HistoryFile()
42 {
43     MaxLinesToRead = DEFAULT_HISTORY_FILE_MAX_LINES;
44     my_history_filename.erase();
45 }
46 /*------------------------------------------------------------------------*/
47 HistoryFile::~HistoryFile()
48 {
49     this->reset();
50 }
51 /*------------------------------------------------------------------------*/
52 std::string HistoryFile::getFilename(void)
53 {
54     if (this->my_history_filename.empty())
55     {
56         this->setDefaultFilename();
57     }
58     return this->my_history_filename;
59 }
60 /*------------------------------------------------------------------------*/
61 void HistoryFile::setFilename(std::string filename)
62 {
63     if (!filename.empty())
64     {
65         this->my_history_filename.erase();
66         this->my_history_filename = filename;
67     }
68     else
69     {
70         this->setDefaultFilename();
71     }
72 }
73 /*------------------------------------------------------------------------*/
74 BOOL HistoryFile::setDefaultFilename(void)
75 {
76     const ScilabPreferences* prefs = getScilabPreferences();
77     if (prefs != NULL)
78     {
79         const char* prefHistoryFile = prefs->historyFile;
80         this->setFilename(expandPathVariable((char*)prefHistoryFile));
81         return TRUE;
82     }
83     else
84     {
85         std::string filename(DEFAULT_HISTORY_FILE);
86         char *SCIHOME = getSCIHOME();
87         if (SCIHOME)
88         {
89             std::string scihome(SCIHOME);
90             std::string sep(DIR_SEPARATOR);
91             this->setFilename(scihome + sep + filename);
92             return TRUE;
93         }
94         else
95         {
96             this->setFilename(filename);
97             return FALSE;
98         }
99     }
100 }
101
102 /*------------------------------------------------------------------------*/
103 BOOL HistoryFile::writeToFile(std::string filename)
104 {
105     BOOL bOK = FALSE;
106
107     if (this->Commands.empty())
108     {
109         return bOK;
110     }
111     else
112     {
113         FILE *pFile = NULL;
114
115         if (filename.empty())
116         {
117             return bOK;
118         }
119
120         wcfopen(pFile , (char*)filename.c_str(), "wt");
121
122         if (pFile)
123         {
124             list<CommandLine>::iterator it_commands;
125             for (it_commands = this->Commands.begin(); it_commands != this->Commands.end(); ++it_commands)
126             {
127                 std::string line = (*it_commands).get();
128                 if (!line.empty())
129                 {
130                     fputs(line.c_str(), pFile);
131                     fputs("\n", pFile);
132                 }
133             }
134             fclose(pFile);
135             bOK = TRUE;
136         }
137     }
138     return bOK;
139 }
140 /*------------------------------------------------------------------------*/
141 BOOL HistoryFile::writeToFile(void)
142 {
143     BOOL bOK = FALSE;
144     if (!this->my_history_filename.empty())
145     {
146         bOK = this->writeToFile(my_history_filename);
147     }
148     return bOK;
149 }
150 /*------------------------------------------------------------------------*/
151 errorLoadHistoryCode HistoryFile::loadFromFile(std::string filename)
152 {
153     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
154     int fd = 0;
155     int f_swap = 0;
156     double res = 0.0;
157     int errMOPEN = MOPEN_INVALID_STATUS;
158     double dErrClose = 0.;
159
160
161     C2F(mopen)(&fd, (char*)filename.c_str(), "rt", &f_swap, &res, &errMOPEN);
162     if (errMOPEN == MOPEN_NO_ERROR)
163     {
164         int errMGETL = MGETL_ERROR;
165         int nblines = 0;
166         char **lines = mgetl(fd, -1, &nblines, &errMGETL);
167
168         C2F(mclose)(&fd, &dErrClose);
169         if (errMGETL == MGETL_NO_ERROR)
170         {
171             if (lines)
172             {
173                 int iStart = 0;
174                 int iEnd = 0;
175                 if (nblines > getDefaultMaxNbLines())
176                 {
177                     iStart = nblines - getDefaultMaxNbLines();
178                     returnedError = HISTORY_TRUNCATED;
179                 }
180                 else
181                 {
182                     iStart = 0;
183                     returnedError = NO_ERROR_HISTORY_LOADED;
184                 }
185                 iEnd = nblines;
186
187                 for (int i = iStart; i < iEnd; i++)
188                 {
189                     CommandLine Line(lines[i]);
190                     this->Commands.push_back(Line);
191                 }
192                 freeArrayOfString(lines, nblines);
193                 lines = NULL;
194             }
195         }
196     }
197     return returnedError;
198 }
199 /*------------------------------------------------------------------------*/
200 errorLoadHistoryCode HistoryFile::loadFromFile(void)
201 {
202     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
203     if (!this->my_history_filename.empty())
204     {
205         returnedError = this->loadFromFile(my_history_filename);
206     }
207     return returnedError;
208 }
209 /*------------------------------------------------------------------------*/
210 list<CommandLine> HistoryFile::getHistory(void)
211 {
212     list <CommandLine> lines(Commands);
213     return lines;
214 }
215 /*------------------------------------------------------------------------*/
216 BOOL HistoryFile::setHistory(list<CommandLine> commands)
217 {
218     BOOL bOK = FALSE;
219     list<CommandLine>::iterator it_commands;
220
221     if (!this->Commands.empty())
222     {
223         this->Commands.clear();
224     }
225
226     for (it_commands = commands.begin(); it_commands != commands.end(); ++it_commands)
227     {
228         std::string line = (*it_commands).get();
229         if (!line.empty())
230         {
231             CommandLine Line(line);
232             this->Commands.push_back(Line);
233         }
234     }
235     return bOK;
236 }
237 /*------------------------------------------------------------------------*/
238 BOOL HistoryFile::reset(void)
239 {
240     BOOL bOK = FALSE;
241     BOOL check1 = FALSE, check2 = FALSE;
242
243     if (!this->Commands.empty())
244     {
245         this->Commands.clear();
246         check1 = TRUE;
247     }
248
249     if (!my_history_filename.empty())
250     {
251         my_history_filename.erase();
252         check2 = TRUE;
253     }
254
255     if (check1 && check2)
256     {
257         bOK = TRUE;
258     }
259
260     return bOK;
261 }
262 /*------------------------------------------------------------------------*/
263 int HistoryFile::getDefaultMaxNbLines(void)
264 {
265     return MaxLinesToRead;
266 }
267 /*------------------------------------------------------------------------*/
268 BOOL HistoryFile::setDefaultMaxNbLines(int nbLinesMax)
269 {
270     BOOL bOK = FALSE;
271     if (nbLinesMax > 0)
272     {
273         MaxLinesToRead = nbLinesMax;
274         bOK = TRUE;
275     }
276     return bOK;
277 }
278 /*------------------------------------------------------------------------*/