warnings visual + intel (all warnings mode) completion module
[scilab.git] / scilab / modules / completion / src / c / completeLine.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009-2010 - DIGITEO - Allan CORNET
4 * Copyright (C) 2010 - DIGITEO - Vincent LEJEUNE
5 * Copyright (C) 2011 - DIGITEO - Allan CORNET
6
7 * This file must be used under the terms of the CeCILL.
8 * This source file is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution.  The terms
10 * are also available at    
11 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12 *
13 */
14
15 /*--------------------------------------------------------------------------*/
16 #include <string.h>
17 #include "completeLine.h"
18 #include "MALLOC.h"
19 #ifdef _MSC_VER
20 #include "strdup_windows.h"
21 #endif
22 #include "getPartLine.h"
23 #include "splitpath.h"
24 #include "PATH_MAX.h"
25 /*--------------------------------------------------------------------------*/
26 /*!  Get the position of the longest suffix of string that match with a prefix of find
27 *  @param[in] string  A string that has a suffix that match a prefix of find ; Assumed to be non null because of the first guard in completeLine
28 *  @param[in] find A string that has a prefix that match with a suffix of string
29 *  @return Position in string where suffix of string and prefix of find does match
30 *
31 */
32 static int findMatchingPrefixSuffix(const char* string, const char* find, BOOL stringToAddIsPath)
33 {
34     char* pointerOnString = NULL;
35     char* pointerOnFindCopy = NULL;
36     char* movingPointerOnFindCopy = NULL;
37     char lastchar;
38     size_t stringLength = 0;
39
40     //get a working copy of find
41     pointerOnFindCopy = strdup(find);
42     //last character of string
43     lastchar = *(string+strlen(string)-1);
44     stringLength = strlen(string);
45
46     //Tips : no infinite loop there, tmpfind string length is always reduced at each iteration
47
48 #ifdef _MSC_VER
49     movingPointerOnFindCopy = strrchr(pointerOnFindCopy, lastchar);
50     // On Windows paths are not case sensitive
51     if (movingPointerOnFindCopy == NULL && stringToAddIsPath)
52     {
53         movingPointerOnFindCopy = strrchr(pointerOnFindCopy, toupper(lastchar));
54     }
55 #else
56     movingPointerOnFindCopy = strrchr(pointerOnFindCopy, lastchar);
57 #endif
58     while( movingPointerOnFindCopy )
59     {
60         //find the last occurence of last char of string in tmpfind
61 #ifdef _MSC_VER
62         movingPointerOnFindCopy = strrchr(pointerOnFindCopy, lastchar);
63         // On Windows paths are not case sensitive
64         if (movingPointerOnFindCopy == NULL && stringToAddIsPath)
65         {
66             movingPointerOnFindCopy = strrchr(pointerOnFindCopy, toupper(lastchar));
67         }
68 #else
69         movingPointerOnFindCopy = strrchr(pointerOnFindCopy, lastchar);
70 #endif
71         if(movingPointerOnFindCopy == NULL)
72         {
73             break;
74         }
75         // Cut tmpfind at this position
76         movingPointerOnFindCopy[0] = '\0';
77         //Check if the cutted tmpfind match with the suffix of string that has adequat length
78         pointerOnString = (char*)(string + stringLength - 1 - strlen(pointerOnFindCopy));
79         if( !strncmp(pointerOnFindCopy, pointerOnString, strlen(pointerOnFindCopy)) )
80         {
81             FREE(pointerOnFindCopy);
82             pointerOnFindCopy = NULL;
83             return (int)(pointerOnString - string);
84         }
85
86     }
87     //if no return, no position is correct, return last char of string.
88     FREE(pointerOnFindCopy);
89     pointerOnFindCopy = NULL;
90     return (int)stringLength;
91 }
92 /*--------------------------------------------------------------------------*/
93 char *completeLine(char *currentline,char *stringToAdd,char *filePattern,
94     char *defaultPattern,BOOL stringToAddIsPath, char *postCaretLine)
95 {
96     char *new_line = NULL;
97     int lengthNewLine = 0;
98
99     char *stringToAddAtTheEnd = NULL;
100     int lenstringToAddAtTheEnd = 0;
101
102     char *res = NULL;
103
104     int lencurrentline = 0;
105     int lenstringToAdd = 0;
106
107     int iposInsert = 0;
108
109     if (currentline == NULL) 
110     {
111         return  strdup("");
112     }
113     lencurrentline = (int)strlen(currentline);
114
115     if (postCaretLine == NULL)
116     {
117         stringToAddAtTheEnd = strdup("");
118         lenstringToAddAtTheEnd = (int)strlen(stringToAddAtTheEnd);
119     }
120     else
121     {
122         stringToAddAtTheEnd = strdup(postCaretLine);
123         lenstringToAddAtTheEnd = (int)strlen(stringToAddAtTheEnd);
124     }
125
126     if ( (stringToAdd == NULL)  || (strcmp(stringToAdd, "") == 0) )
127     {
128         lengthNewLine = lencurrentline + lenstringToAddAtTheEnd;
129         new_line = (char*)MALLOC(sizeof(char) * (lengthNewLine + 1));
130         if (new_line)
131         {
132             strcpy(new_line, currentline);
133             strcat(new_line, stringToAddAtTheEnd);
134         }
135
136         if (stringToAddAtTheEnd) {FREE(stringToAddAtTheEnd); stringToAddAtTheEnd = NULL;}
137
138         return new_line;
139     }
140
141     if (stringToAddIsPath == FALSE)
142     {
143         char *filePatternBuf = NULL;
144         BOOL bfilePatternBuf = FALSE;
145
146         if (filePattern != NULL)
147         {
148             filePatternBuf = filePattern;
149         }
150         else
151         {
152             filePatternBuf = getFilePartLevel(currentline);
153             bfilePatternBuf = TRUE;
154         }
155
156         if (filePatternBuf)
157         {
158             char* drv = (char*)MALLOC(sizeof(char)*(PATH_MAX+1));
159             char* dir = (char*)MALLOC(sizeof(char)*(PATH_MAX+1));
160             char* name = (char*)MALLOC(sizeof(char)*(PATH_MAX+1));
161             char* ext = (char*)MALLOC(sizeof(char)*(PATH_MAX+1));
162
163             splitpath(filePatternBuf,TRUE, drv,dir, name, ext);
164
165             if (bfilePatternBuf)
166             {
167                 FREE(filePatternBuf);
168                 filePatternBuf = NULL;
169                 bfilePatternBuf = FALSE;
170             }
171
172             if ( strcmp(drv,"") || strcmp(dir,"") )
173             {
174                 /* bug 4365 */
175                 /*cd SCI/modules/arnoldi/nonreg_tes */
176
177                 if (drv) {FREE(drv); drv = NULL;}
178                 if (dir) {FREE(dir); dir = NULL;}
179                 if (name) {FREE(name); name = NULL;}
180                 if (ext) {FREE(ext); ext = NULL;}
181
182                 lengthNewLine = lencurrentline + lenstringToAddAtTheEnd;
183                 new_line = (char*)MALLOC(sizeof(char) * (lengthNewLine + 1));
184                 if (new_line)
185                 {
186                     strcpy(new_line, currentline);
187                     strcat(new_line, stringToAddAtTheEnd);
188                 }
189
190                 if (stringToAddAtTheEnd) {FREE(stringToAddAtTheEnd); stringToAddAtTheEnd = NULL;}
191
192                 return new_line;
193             }
194
195             if (drv) {FREE(drv); drv = NULL;}
196             if (dir) {FREE(dir); dir = NULL;}
197             if (name) {FREE(name); name = NULL;}
198             if (ext) {FREE(ext); ext = NULL;}
199         }
200     }
201
202     lenstringToAdd = (int)strlen(stringToAdd);
203     iposInsert = findMatchingPrefixSuffix(currentline, stringToAdd, stringToAddIsPath);
204     res = strstr(stringToAdd, &currentline[iposInsert]);
205
206     if (res == NULL)
207     {
208         // We found "pattern"
209         // if it is a path, we add at the end
210         if ((currentline[lencurrentline - 1] == '/') || (currentline[lencurrentline - 1] == '\\'))
211         {
212             iposInsert = lencurrentline;
213         }
214         else
215         {
216             iposInsert = lencurrentline - 1;
217         }
218     }
219     else
220     {
221         // if it is a path, we add at the end
222         if ((currentline[lencurrentline - 1] == '/') || (currentline[lencurrentline - 1] == '\\'))
223         {
224             iposInsert = lencurrentline;
225         }
226     }
227
228     lengthNewLine = (int)(strlen(currentline)+ strlen(stringToAdd) + lenstringToAddAtTheEnd);
229     new_line = (char*)MALLOC(sizeof(char)*(lengthNewLine + 1));
230     if (new_line)
231     {
232         strcpy(new_line, currentline);
233         new_line[iposInsert] = 0;
234
235         strcat(new_line, stringToAdd);
236         strcat(new_line, stringToAddAtTheEnd);
237     }
238
239     if (stringToAddAtTheEnd) {FREE(stringToAddAtTheEnd); stringToAddAtTheEnd = NULL;}
240
241     return new_line;
242 }
243 /*--------------------------------------------------------------------------*/