OSDN Git Service

Fix for linux build
[dennco/dennco.git] / Source / DNUtils.cpp
1 //  Copyright (c) 2012 Dennco Project
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 //
17 //  Created by tkawata on 1/7/2012.
18 //
19
20 #include "DNUtils.h"
21 #include "TKLog.h"
22 #include "TKDebug.h"
23
24 #ifndef _MSC_VER
25     #include <string.h>
26     #include <stdlib.h>
27 #endif
28
29 void trimString(std::string& str)
30 {
31     std::string::size_type pos1 = str.find_first_not_of(' ');
32     std::string::size_type pos2 = str.find_last_not_of(' ');
33     std::string::size_type pos1_2 = str.find_first_not_of('\t');
34     std::string::size_type pos2_2 = str.find_last_not_of('\t');
35     
36     pos1 = pos1 < pos1_2 ? pos1_2 : pos1;
37     pos2 = pos2 < pos2_2 ? pos2_2 : pos2;
38     
39     str = str.substr(pos1 == std::string::npos ? 0 : pos1, 
40                      pos2 == std::string::npos ? str.length() - 1 : pos2 - pos1 + 1);
41 }
42 std::string parseCellCodeForScriptEngine(std::string jname, std::string cellCode)
43 {
44 #ifdef DEBUG
45     DEBUG_TRACE("TKJSCellCode::TKJSCellCode() parse for %s\n=== Original code =====\n%s\n", jname.c_str(), cellCode.c_str());
46 #endif
47
48     const char *c = cellCode.c_str();
49
50     int  inComment1 = 0;   //  //
51     int  inComment2 = 0;   //  /* ... */
52     int  inComment2_end = 0;
53     int  inFunction = 0;
54     int  inVar = 0;
55     int  inQuote = 0;
56     int  inDoubleQuote = 0;
57     int  nest = 0;
58     const char *sp = 0;
59     int  l = 0;
60     int  lp = 0;
61     std::string funcs = "";
62     std::string vars = "";
63     std::string fff = "";
64
65     const char* str_comment1 = "//";
66     const char* str_comment2 = "/*";
67     const char* str_comment2_end = "*/";
68     const char* str_function = "function";
69     const char* str_var = "var";
70
71     while (*c)
72     {
73         if (*c == '\r' || *c == '\n')
74         {
75             lp = 0;
76         }
77         else if (*c != ' ' && *c != '\t')
78         {
79             lp++;
80         }
81
82         if (inComment1 == -1)
83         {
84             if (*c == '\r' || *c == '\n' )
85                 inComment1 = 0;
86             c++;
87             continue;
88         }
89         else if (inComment2 == -1)
90         {
91             if (*c == str_comment2_end[inComment2_end])
92             {
93                 inComment2_end ++;
94                 if (str_comment2_end[inComment2_end] == 0)
95                 {
96                     inComment2 = 0;
97                     inComment2_end = 0;
98                 }
99             }
100             else
101             {
102                 inComment2_end = 0;
103             }
104             c++;
105             continue;
106         }
107
108         if (inQuote == -1)
109         {
110             if (*c == '\\')
111             {
112                 c++;
113                 if (*c != 0)c++;
114                 continue;
115             }
116             if (*c == '\'')
117             {
118                 inQuote = 0;
119             }
120             c++;
121             continue;
122         }
123         else if (inDoubleQuote == -1)
124         {
125             if (*c == '\\')
126             {
127                 c++;
128                 if (*c != 0)c++;
129                 continue;
130             }
131             if (*c == '\"')
132             {
133                 inDoubleQuote = 0;
134             }
135             c++;
136             continue;
137         }
138
139         if (*c == '\'')
140         {
141             inQuote = -1;
142             c++;
143             continue;
144         }
145
146         if (*c == '\"')
147         {
148             inDoubleQuote = -1;
149             c++;
150             continue;
151         }
152
153         //IN COMMENT?
154         if (*c == str_comment1[inComment1])
155         {
156             inComment1++;
157             if (str_comment1[inComment1] == 0)
158             {
159                 inComment1 = -1;
160                 c++;
161                 continue;
162             }
163         }
164         else
165         {
166             inComment1 = 0;
167         }
168
169         if (*c == str_comment2[inComment2])
170         {
171             inComment2++;
172             if (str_comment2[inComment2] == 0)
173             {
174                 inComment2 = -1;
175                 c++;
176                 continue;
177             }
178         }
179         else
180         {
181             inComment2 = 0;
182         }
183
184         if (!inComment1 && !inComment2 && !inQuote && !inDoubleQuote && *c == '{')
185         {
186             nest++;
187             if (inFunction == -1 && nest == 1)
188             {
189                 fff = "";
190                 fff.append(sp,c-sp+1);
191                 unsigned long fp = fff.find( "(", 0 );
192                 if( fp != std::string::npos )
193                 {
194                     fff = fff.substr(0, fp);
195                     trimString(fff);
196                     sp += fp;
197                 }
198                 else
199                 {
200                     inFunction  = 0;
201                 }
202             }
203         }
204         else if (!inComment1 && !inComment2 && !inQuote && !inDoubleQuote && *c == '}')
205         {
206             nest--;
207             if (nest == 0)
208             {
209                 if (inFunction == -1)
210                 {
211                     //FUNCTION DEF
212                     std::string fn = "";
213                     funcs.append(jname);
214                     funcs.append(".prototype.");
215                     funcs.append(fff);
216                     funcs.append(" = function");
217                     funcs.append(sp ,c-sp+1);
218                     funcs.append("\r\n");
219                     inFunction = 0;
220                 }
221             }
222             c++;
223             continue;
224         }
225
226         if (*c == ';')
227         {
228             if (inVar == -1)
229             {
230                 //VAR DEF
231                 std::string t = "";
232                 t.append(sp,c-sp+1);
233                 trimString(t);
234                 vars.append("this.");
235                 vars.append(t);
236                 vars.append("\r\n");
237                 inVar = 0;
238             }
239             c++;
240             continue;
241         }
242
243         if (inFunction == -1)
244         {
245             if (l == 0) {
246                 if (*c != ' ' && *c != '\t' && *c != '\r' && *c != '\n')
247                 {
248                     inFunction =0;
249                     c++;
250                     l = 0;
251                     continue;
252                 }
253             }
254             c++;
255             l++;
256             continue;
257         }
258
259         if (inVar == -1)
260         {
261             if (l == 0) {
262                 if (*c != ' ' && *c != '\t' && *c != '\r' && *c != '\n' && *c != '=')
263                 {
264                     inVar =0;
265                     c++;
266                     l = 0;
267                     continue;
268                 }
269             }
270             c++;
271             l++;
272             continue;
273         }
274
275
276         if (nest == 0 && *c == str_function[inFunction] && (inFunction+1) == lp)
277         {
278             inFunction++;
279             if (str_function[inFunction] == 0)
280             {
281                 inFunction = -1;
282                 sp = c+1;
283                 l = 0;
284             }
285             c++;
286             continue;
287         }
288
289         if (nest == 0 && *c == str_var[inVar] && (inVar+1) == lp)
290         {
291             inVar++;
292             if (str_var[inVar] == 0)
293             {
294                 inVar = -1;
295                 sp = c+1;
296                 l = 0;
297             }
298             c++;
299             continue;
300         }
301
302         c++;
303
304     }
305
306     std::string stmt = "";
307     stmt.append("function ");
308     stmt.append(jname);
309     stmt.append("(ownerCell)\n{\nthis.cell = ownerCell;\n");
310     stmt.append(vars);
311     stmt.append("\n}\n");
312     stmt.append(funcs);
313 #ifdef DEBUG
314     DEBUG_TRACE("\n\n==== Translated JS statement:=====\n%s\n=====\n", stmt.c_str());
315 #endif
316     return stmt;
317 }
318
319 std::string getFQNString(const char *location, const char *name)
320 {
321     std::string path;
322     std::string node;
323     int l = (int)strlen(location) - 1;
324     bool f = false;
325     while (l >= 0)
326     {
327         if (location[l] == '/')
328         {
329             f = true;
330             break;
331         }
332         l--;
333     }
334     if( f )
335     {
336         if (l == 0)
337         {
338             path = "/";
339             node = location;
340         }
341         else
342         {
343             node = location;
344             path = node.substr(0,l);
345             node = node.substr(l);
346         }
347     }
348     else
349     {
350         path = "";
351         node = location;
352     }
353     
354     const char *c = name;
355     int i = 0;
356     const char *p = c;
357     while(*c)
358     {
359         if (*c == '/')
360         {
361             if (i >= 2 && *(c - 2) == '.' && *(c - 1) == '.')
362             {
363                 unsigned long l = path.find_last_of("/");
364                 if( l != std::string::npos )
365                 {
366                     if (l == 0)
367                     {
368                         path = "/";
369                     }
370                     else if (l > 0)
371                     {
372                         path = path.substr(0, l);
373                     }
374                 }
375                 else
376                 {
377                     path = "";
378                 }
379                 p = c;
380             }
381             else if (i >= 1 && *(c - 1) == '.')
382             {
383                 p = c;
384             }
385             else if (i >= 1 && *(c - 1) == '/')
386             {
387                 p = c; 
388             }
389             else if (i == 0)
390             {
391                 if (path.length() > 0 && path.at(0) == '/')
392                 {
393                     path = "/";
394                 }
395                 else
396                 {
397                     path = "";
398                 }
399             }
400             else
401             {
402                 size_t pl = path.length();
403                 if (pl == 0)
404                 {
405                     if (*p == '/')
406                     {
407                         p++;
408                     }                    
409                 }
410                 else if (pl == 1)
411                 {
412                     char p1 = path.at(0);
413                     if (p1 == '/' || p1 == '.')
414                     {
415                         if (*p == '/')
416                         {
417                             p++;
418                         }
419                     }
420                 }
421                 else
422                 {
423                     if (*p != '/')
424                     {
425                         path.append("/");
426                     }
427                 }
428                 std::string s(p, c-p); 
429                 path.append(s);
430                 p = c;
431             }
432         }
433         c++;
434         i++;
435         if (i > 1024) break;
436     }
437     
438     if (*p == '/')
439     {
440         node = p;
441     }
442     else if(*p == '#')
443     {
444         node.append(p);
445     }
446     else
447     {
448         const char *p2 = p;
449         bool hasAnchor = false;
450         while(*p2)
451         {
452             if (*p2 == '#')
453             {
454                 hasAnchor = true;
455                 break;
456             }
457             p2++;
458         }
459         if (hasAnchor)
460         {
461             node = "/";
462             node.append(p);        
463         }
464         else
465         {
466             node.append("#");
467             node.append(p);
468         }
469     }
470     
471     int pl = (int)path.length();
472     std::string fqn;
473     if (pl == 0)
474     {
475         if (node.at(0) == '/' && node.length() > 1)
476         {
477             fqn = node.substr(1);
478         }
479         else
480         {
481             fqn = node;
482         }
483         
484     }
485     else if (pl == 1)
486     {
487         if (path.at(0) == '/' && node.length() > 0 && node.at(0) == '/')
488         {
489             fqn = node;
490         }
491         else
492         {
493             fqn = path.append(node);
494         }
495     }
496     else
497     {
498         fqn = path.append(node);
499     }
500     
501     return fqn;
502 }
503
504 std::string getJSEscapeString(const char *cstring)
505 {
506     const char *c = cstring; 
507     std::string result = "";
508     while(*c)
509     {
510         if (*c == '/')
511         {
512             result.append("_s");
513         }
514         else if (*c == '_')
515         {
516             result.append("__");
517         }
518         else if (*c == '.')
519         {
520             result.append("_d");
521         }
522         else if (*c == '#')
523         {
524             result.append("_S");
525         }
526         else
527         {
528             result.append(1,*c);
529         }
530         
531         c++;
532     }
533
534     return result;
535 }
536