packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmDependsJavaParserHelper.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmDependsJavaParserHelper.h"
13
14 #include "cmSystemTools.h"
15 #include "cmDependsJavaLexer.h"
16
17 int cmDependsJava_yyparse( yyscan_t yyscanner );
18
19 cmDependsJavaParserHelper::cmDependsJavaParserHelper()
20 {
21   this->CurrentDepth = 0;
22
23   this->UnionsAvailable = 0;
24   this->LastClassId = 0;
25
26   CurrentClass tl;
27   tl.Name = "*";
28   this->ClassStack.push_back(tl);
29 }
30
31
32 cmDependsJavaParserHelper::~cmDependsJavaParserHelper()
33 {
34   this->CleanupParser();
35 }
36
37 void cmDependsJavaParserHelper::CurrentClass
38 ::AddFileNamesForPrinting(std::vector<cmStdString> *files,
39                           const char* prefix, const char* sep)
40 {
41   cmStdString rname = "";
42   if ( prefix )
43     {
44     rname += prefix;
45     rname += sep;
46     }
47   rname += this->Name;
48   files->push_back(rname);
49   std::vector<CurrentClass>::iterator it;
50   for ( it = this->NestedClasses->begin();
51     it != this->NestedClasses->end();
52     ++ it )
53     {
54     it->AddFileNamesForPrinting(files, rname.c_str(), sep);
55     }
56 }
57
58 void cmDependsJavaParserHelper::DeallocateParserType(char** pt)
59 {
60   if (!pt)
61     {
62     return;
63     }
64   if (!*pt)
65     {
66     return;
67     }
68   *pt = 0;
69   this->UnionsAvailable --;
70 }
71
72 void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
73 {
74   if( ! sclass )
75     {
76     return;
77     }
78   std::vector<cmStdString>::iterator it;
79   for ( it = this->ClassesFound.begin();
80     it != this->ClassesFound.end();
81     it ++ )
82     {
83     if ( *it == sclass )
84       {
85       return;
86       }
87     }
88   this->ClassesFound.push_back(sclass);
89 }
90
91 void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
92 {
93   std::vector<cmStdString>::iterator it;
94   for ( it = this->PackagesImport.begin();
95     it != this->PackagesImport.end();
96     it ++ )
97     {
98     if ( *it == sclass )
99       {
100       return;
101       }
102     }
103   this->PackagesImport.push_back(sclass);
104 }
105
106 void cmDependsJavaParserHelper::SafePrintMissing(const char* str,
107                                                  int line, int cnt)
108 {
109   if ( str )
110     {
111     std::cout << line << " String " << cnt << " exists: ";
112     unsigned int cc;
113     for ( cc = 0; cc < strlen(str); cc ++ )
114       {
115       unsigned char ch = str[cc];
116       if ( ch >= 32 && ch <= 126 )
117         {
118         std::cout << (char)ch;
119         }
120       else
121         {
122         std::cout << "<" << (int)ch << ">";
123         break;
124         }
125       }
126     std::cout << "- " << strlen(str) << std::endl;
127     }
128 }
129 void cmDependsJavaParserHelper::Print(const char* place, const char* str)
130 {
131   if ( this->Verbose )
132     {
133     std::cout << "[" << place << "=" << str << "]" << std::endl;
134     }
135 }
136
137 void cmDependsJavaParserHelper::CombineUnions(char** out,
138                                               const char* in1, char** in2,
139                                               const char* sep)
140 {
141   size_t len = 1;
142   if ( in1 )
143     {
144     len += strlen(in1);
145     }
146   if ( *in2 )
147     {
148     len += strlen(*in2);
149     }
150   if ( sep )
151     {
152     len += strlen(sep);
153     }
154   *out = new char [ len ];
155   *out[0] = 0;
156   if ( in1 )
157     {
158     strcat(*out, in1);
159     }
160   if ( sep )
161     {
162     strcat(*out, sep);
163     }
164   if ( *in2 )
165     {
166     strcat(*out, *in2);
167     }
168   if ( *in2 )
169     {
170     this->DeallocateParserType(in2);
171     }
172   this->UnionsAvailable ++;
173 }
174
175 void cmDependsJavaParserHelper
176 ::CheckEmpty(int line, int cnt, cmDependsJavaParserHelper::ParserType* pt)
177 {
178   int cc;
179   int kk = -cnt + 1;
180   for ( cc = 1; cc <= cnt; cc ++)
181     {
182     cmDependsJavaParserHelper::ParserType* cpt = pt + kk;
183     this->SafePrintMissing(cpt->str, line, cc);
184     kk ++;
185     }
186 }
187
188 void cmDependsJavaParserHelper
189 ::PrepareElement(cmDependsJavaParserHelper::ParserType* me)
190 {
191   // Inititalize self
192   me->str = 0;
193 }
194
195 void cmDependsJavaParserHelper
196 ::AllocateParserType(cmDependsJavaParserHelper::ParserType* pt,
197                      const char* str, int len)
198 {
199   pt->str = 0;
200   if ( len == 0 )
201     {
202     len = (int)strlen(str);
203     }
204   if ( len == 0 )
205     {
206     return;
207     }
208   this->UnionsAvailable ++;
209   pt->str = new char[ len + 1 ];
210   strncpy(pt->str, str, len);
211   pt->str[len] = 0;
212   this->Allocates.push_back(pt->str);
213 }
214
215 void cmDependsJavaParserHelper::StartClass(const char* cls)
216 {
217   CurrentClass cl;
218   cl.Name = cls;
219   this->ClassStack.push_back(cl);
220
221   this->CurrentDepth ++;
222 }
223
224 void cmDependsJavaParserHelper::EndClass()
225 {
226   CurrentClass* parent = 0;
227   CurrentClass* current = 0;
228   if ( this->ClassStack.size() > 0 )
229     {
230     current = &(*(this->ClassStack.end() - 1));
231     if ( this->ClassStack.size() > 1 )
232       {
233       parent = &(*(this->ClassStack.end() - 2));
234       }
235     }
236   if ( current == 0 )
237     {
238     std::cerr << "Error when parsing. Current class is null" << std::endl;
239     abort();
240     }
241   if ( parent == 0 )
242     {
243     std::cerr << "Error when parsing. Parent class is null" << std::endl;
244     abort();
245     }
246   this->CurrentDepth --;
247   parent->NestedClasses->push_back(*current);
248   this->ClassStack.erase(this->ClassStack.end()-1, this->ClassStack.end());
249 }
250
251 void cmDependsJavaParserHelper::PrintClasses()
252 {
253   if ( this->ClassStack.size() == 0 )
254     {
255     std::cerr << "Error when parsing. No classes on class stack" << std::endl;
256     abort();
257     }
258   std::vector<cmStdString> files = this->GetFilesProduced();
259   std::vector<cmStdString>::iterator sit;
260   for ( sit = files.begin();
261     sit != files.end();
262     ++ sit )
263     {
264     std::cout << "  " << sit->c_str() << ".class" << std::endl;
265     }
266 }
267
268 std::vector<cmStdString> cmDependsJavaParserHelper::GetFilesProduced()
269 {
270   std::vector<cmStdString> files;
271   CurrentClass* toplevel = &(*(this->ClassStack.begin()));
272   std::vector<CurrentClass>::iterator it;
273   for ( it = toplevel->NestedClasses->begin();
274     it != toplevel->NestedClasses->end();
275     ++ it )
276     {
277     it->AddFileNamesForPrinting(&files, 0, "$");
278     }
279   return files;
280 }
281
282 int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
283 {
284   if ( !str)
285     {
286     return 0;
287     }
288   this->Verbose = verb;
289   this->InputBuffer = str;
290   this->InputBufferPos = 0;
291   this->CurrentLine = 0;
292
293
294   yyscan_t yyscanner;
295   cmDependsJava_yylex_init(&yyscanner);
296   cmDependsJava_yyset_extra(this, yyscanner);
297   int res = cmDependsJava_yyparse(yyscanner);
298   cmDependsJava_yylex_destroy(yyscanner);
299   if ( res != 0 )
300     {
301     std::cout << "JP_Parse returned: " << res << std::endl;
302     return 0;
303     }
304
305   if ( verb )
306     {
307     if ( this->CurrentPackage.size() > 0 )
308       {
309       std::cout << "Current package is: " <<
310         this->CurrentPackage.c_str() << std::endl;
311       }
312     std::cout << "Imports packages:";
313     if ( this->PackagesImport.size() > 0 )
314       {
315       std::vector<cmStdString>::iterator it;
316       for ( it = this->PackagesImport.begin();
317         it != this->PackagesImport.end();
318         ++ it )
319         {
320         std::cout << " " << it->c_str();
321         }
322       }
323     std::cout << std::endl;
324     std::cout << "Depends on:";
325     if ( this->ClassesFound.size() > 0 )
326       {
327       std::vector<cmStdString>::iterator it;
328       for ( it = this->ClassesFound.begin();
329         it != this->ClassesFound.end();
330         ++ it )
331         {
332         std::cout << " " << it->c_str();
333         }
334       }
335     std::cout << std::endl;
336     std::cout << "Generated files:" << std::endl;
337     this->PrintClasses();
338     if ( this->UnionsAvailable != 0 )
339       {
340       std::cout << "There are still " <<
341         this->UnionsAvailable << " unions available" << std::endl;
342       }
343     }
344   this->CleanupParser();
345   return 1;
346 }
347
348 void cmDependsJavaParserHelper::CleanupParser()
349 {
350   std::vector<char*>::iterator it;
351   for ( it = this->Allocates.begin();
352     it != this->Allocates.end();
353     ++ it )
354     {
355     delete [] *it;
356     }
357   this->Allocates.erase(this->Allocates.begin(),
358     this->Allocates.end());
359 }
360
361 int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
362 {
363   if ( maxlen < 1 )
364     {
365     return 0;
366     }
367   if ( this->InputBufferPos < this->InputBuffer.size() )
368     {
369     buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
370     if ( buf[0] == '\n' )
371       {
372       this->CurrentLine ++;
373       }
374     return(1);
375     }
376   else
377     {
378     buf[0] = '\n';
379     return( 0 );
380     }
381 }
382 void cmDependsJavaParserHelper::Error(const char* str)
383 {
384   unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
385   fprintf(stderr, "JPError: %s (%lu / Line: %d)\n",
386           str, pos, this->CurrentLine);
387   int cc;
388   std::cerr << "String: [";
389   for ( cc = 0;
390         cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
391         cc ++ )
392     {
393     std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
394     }
395   std::cerr << "]" << std::endl;
396 }
397
398 void cmDependsJavaParserHelper::UpdateCombine(const char* str1,
399                                               const char* str2)
400 {
401   if ( this->CurrentCombine == "" && str1 != 0)
402     {
403     this->CurrentCombine = str1;
404     }
405   this->CurrentCombine += ".";
406   this->CurrentCombine += str2;
407 }
408
409 int cmDependsJavaParserHelper::ParseFile(const char* file)
410 {
411   if ( !cmSystemTools::FileExists(file))
412     {
413     return 0;
414     }
415   std::ifstream ifs(file);
416   if ( !ifs )
417     {
418     return 0;
419     }
420
421   cmStdString fullfile = "";
422   cmStdString line;
423   while ( cmSystemTools::GetLineFromStream(ifs, line) )
424     {
425     fullfile += line + "\n";
426     }
427   return this->ParseString(fullfile.c_str(), 0);
428 }
429