f491c0e00cd83aaef6c284ab1d6586ea32f0b1ab
[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 };
36 /*------------------------------------------------------------------------*/
37 #define DEFAULT_HISTORY_FILE_MAX_LINES 20000
38 /*------------------------------------------------------------------------*/
39 HistoryFile::HistoryFile()
40 {
41     MaxLinesToRead = DEFAULT_HISTORY_FILE_MAX_LINES;
42     my_history_filename.erase();
43 }
44 /*------------------------------------------------------------------------*/
45 HistoryFile::~HistoryFile()
46 {
47     this->reset();
48 }
49 /*------------------------------------------------------------------------*/
50 std::string HistoryFile::getFilename(void)
51 {
52     if (this->my_history_filename.empty()) this->setDefaultFilename();
53     return this->my_history_filename;
54 }
55 /*------------------------------------------------------------------------*/
56 void HistoryFile::setFilename(std::string filename)
57 {
58     if (!filename.empty())
59     {
60         this->my_history_filename.erase();
61         this->my_history_filename = filename;
62     }
63     else
64     {
65         this->setDefaultFilename();
66     }
67 }
68 /*------------------------------------------------------------------------*/
69 BOOL HistoryFile::setDefaultFilename(void)
70 {
71     BOOL bOK = FALSE;
72     char *SCIHOME = getSCIHOME();
73     std::string defaultfilename;
74     std::string defautlhistoryfile;
75
76     defautlhistoryfile.assign(DEFAULT_HISTORY_FILE);
77
78     if (SCIHOME)
79     {
80         std::string sep;
81         std::string scihome;
82
83         sep.assign(DIR_SEPARATOR);
84         scihome.assign(SCIHOME);
85
86         defaultfilename = scihome + sep + defautlhistoryfile;
87
88         FREE(SCIHOME);
89         SCIHOME = NULL;
90         bOK = TRUE;
91     }
92     else
93     {
94         defaultfilename = defautlhistoryfile;
95         bOK = FALSE;
96         /* this isn't the standard path for history file */
97         /* but we set a filename */
98     }
99
100     this->setFilename(defaultfilename);
101
102     return bOK;
103 }
104 /*------------------------------------------------------------------------*/
105 BOOL HistoryFile::writeToFile(std::string filename)
106 {
107     BOOL bOK = FALSE;
108
109     if (this->Commands.empty()) return bOK;
110     else
111     {
112         FILE *pFile = NULL;
113
114         if (filename.empty())  return bOK;
115
116         wcfopen(pFile , (char*)filename.c_str(), "wt");
117
118         if (pFile)
119         {
120             list<CommandLine>::iterator it_commands;
121             for(it_commands=this->Commands.begin(); it_commands != this->Commands.end(); ++it_commands)
122             {
123                 std::string line = (*it_commands).get();
124                 if (!line.empty())
125                 {
126                     fputs(line.c_str(),pFile);
127                     fputs("\n",pFile);
128                 }
129             }
130             fclose(pFile);
131             bOK = TRUE;
132         }
133     }
134     return bOK;
135 }
136 /*------------------------------------------------------------------------*/
137 BOOL HistoryFile::writeToFile(void)
138 {
139     BOOL bOK = FALSE;
140     if (!this->my_history_filename.empty()) bOK = this->writeToFile(my_history_filename);
141     return bOK;
142 }
143 /*------------------------------------------------------------------------*/
144 errorLoadHistoryCode HistoryFile::loadFromFile(std::string filename)
145 {
146     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
147     int fd = 0;
148     int f_swap = 0;
149     double res = 0.0;
150     int errMOPEN = MOPEN_INVALID_STATUS;
151     double dErrClose = 0.;
152
153
154     C2F(mopen)(&fd, (char*)filename.c_str(), "rt", &f_swap, &res, &errMOPEN);
155     if (errMOPEN == MOPEN_NO_ERROR)
156     {
157         int errMGETL = MGETL_ERROR;
158         int nblines = 0;
159         char **lines = mgetl(fd, -1, &nblines, &errMGETL);
160
161         C2F(mclose)(&fd, &dErrClose);
162         if (errMGETL == MGETL_NO_ERROR)
163         {
164             if (lines)
165             {
166                 int iStart = 0;
167                 int iEnd = 0;
168                 if (nblines > getDefaultMaxNbLines())
169                 {
170                     iStart = nblines - getDefaultMaxNbLines();
171                     returnedError = HISTORY_TRUNCATED;
172                 }
173                 else
174                 {
175                     iStart = 0;
176                     returnedError = NO_ERROR_HISTORY_LOADED;
177                 }
178                 iEnd = nblines;
179
180                 for (int i = iStart; i < iEnd; i++)
181                 {
182                     CommandLine Line(lines[i]);
183                     this->Commands.push_back(Line);
184                 }
185                 freeArrayOfString(lines, nblines);
186                 lines = NULL;
187             }
188         }
189     }
190     return returnedError;
191 }
192 /*------------------------------------------------------------------------*/
193 errorLoadHistoryCode HistoryFile::loadFromFile(void)
194 {
195     errorLoadHistoryCode returnedError = ERROR_HISTORY_NOT_LOADED;
196     if (!this->my_history_filename.empty()) returnedError = this->loadFromFile(my_history_filename);
197     return returnedError;
198 }
199 /*------------------------------------------------------------------------*/
200 list<CommandLine> HistoryFile::getHistory(void)
201 {
202     list <CommandLine> lines(Commands);
203     return lines;
204 }
205 /*------------------------------------------------------------------------*/
206 BOOL HistoryFile::setHistory(list<CommandLine> commands)
207 {
208     BOOL bOK = FALSE;
209     list<CommandLine>::iterator it_commands;
210
211     if (!this->Commands.empty()) this->Commands.clear();
212
213     for(it_commands=commands.begin(); it_commands != commands.end(); ++it_commands)
214     {
215         std::string line = (*it_commands).get();
216         if (!line.empty())
217         {
218             CommandLine Line(line);
219             this->Commands.push_back(Line);
220         }
221     }
222     return bOK;
223 }
224 /*------------------------------------------------------------------------*/
225 BOOL HistoryFile::reset(void)
226 {
227     BOOL bOK = FALSE;
228     BOOL check1 = FALSE,check2 = FALSE;
229
230     if (!this->Commands.empty())
231     {
232         this->Commands.clear();
233         check1 = TRUE;
234     }
235
236     if (!my_history_filename.empty())
237     {
238         my_history_filename.erase();
239         check2 = TRUE;
240     }
241
242     if (check1 && check2) bOK = TRUE;
243
244     return bOK;
245 }
246 /*------------------------------------------------------------------------*/
247 int HistoryFile::getDefaultMaxNbLines(void)
248 {
249     return MaxLinesToRead;
250 }
251 /*------------------------------------------------------------------------*/
252 BOOL HistoryFile::setDefaultMaxNbLines(int nbLinesMax)
253 {
254     BOOL bOK = FALSE;
255     if (nbLinesMax > 0)
256     {
257         MaxLinesToRead = nbLinesMax;
258         bOK = TRUE;
259     }
260     return bOK;
261 }
262 /*------------------------------------------------------------------------*/