source: CMT/v1r25-branch/source/cmt_syntax.cxx

Last change on this file was 664, checked in by rybkin, 10 years ago

merge -r 646:663 HEAD

  • Property svn:eol-style set to native
File size: 50.1 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by garonne@lal.in2p3.fr
5// Modified by Grigory Rybkin
6// See the complete license in cmt_license.txt "http://www.cecill.info".
7//-----------------------------------------------------------
8
9#include "cmt_syntax.h"
10#include "cmt.h"
11#include "cmt_symbol.h"
12#include "cmt_constituent.h"
13#include "cmt_pattern.h"
14#include "cmt_error.h"
15#include "cmt_branch.h"
16#include "cmt_error.h"
17#include "cmt_script.h"
18#include "cmt_language.h"
19#include "cmt_project.h"
20#include "cmt_cmtpath_pattern.h"
21#include "cmt_log.h"
22
23
24class KwdAction : public Kwd
25{
26public:
27  void action (const CmtSystem::cmt_string_vector& words,
28               Use* use,
29               const cmt_string& file_name,
30               int line_number)
31  {
32    Symbol::action (words, CommandAction, use);
33  }
34  void action (const CmtSystem::cmt_string_vector& words,
35               Project* project,
36               const cmt_string& file_name,
37               int line_number)
38  {}
39};
40
41class KwdAlias : public Kwd
42{
43public:
44  void action (const CmtSystem::cmt_string_vector& words,
45               Use* use,
46               const cmt_string& file_name,
47               int line_number)
48  {
49    Symbol::action (words, CommandAlias, use);
50  }
51  void action (const CmtSystem::cmt_string_vector& words,
52               Project* project,
53               const cmt_string& file_name,
54               int line_number)
55  {}
56
57};
58
59class KwdApplication : public Kwd
60{
61public:
62  void action (const CmtSystem::cmt_string_vector& words,
63               Use* use,
64               const cmt_string& file_name,
65               int line_number)
66  {
67    if (use == &(Use::current ()))
68      {
69        Constituent::action (Application, words);
70      }
71  }
72 
73  void action (const CmtSystem::cmt_string_vector& words,
74               Project* project,
75               const cmt_string& file_name,
76               int line_number)
77  {}
78
79};
80
81class KwdApplyPattern : public Kwd
82{
83public:
84  void action (const CmtSystem::cmt_string_vector& words,
85               Use* use,
86               const cmt_string& file_name,
87               int line_number)
88  {
89    ApplyPattern::action (words, use);
90  }
91  void action (const CmtSystem::cmt_string_vector& words,
92               Project* project,
93               const cmt_string& file_name,
94               int line_number)
95  {}
96
97};
98
99class KwdApplyTag : public Kwd
100{
101public:
102  void action (const CmtSystem::cmt_string_vector& words,
103               Use* use,
104               const cmt_string& file_name,
105               int line_number)
106  {
107    Tag::action_apply (words, use);
108  }
109  void action (const CmtSystem::cmt_string_vector& words,
110               Project* project,
111               const cmt_string& file_name,
112               int line_number)
113  {
114    action (words, project->get_use(), file_name, line_number);   
115  }
116
117};
118
119//----------------------------------------------------------
120class KwdAuthor : public Kwd
121{
122public:
123  void action (const CmtSystem::cmt_string_vector& words,
124               Use* use,
125               const cmt_string& file_name,
126               int line_number)
127  {
128    use->author_action (words);
129
130  }
131  void action (const CmtSystem::cmt_string_vector& words,
132               Project* project,
133               const cmt_string& file_name,
134               int line_number)
135  {
136    cmt_string author;
137    project->project_author_action (words);
138  }
139};
140//----------------------------------------------------------
141
142
143class KwdBranches : public Kwd
144{
145public:
146  void action (const CmtSystem::cmt_string_vector& words,
147               Use* use,
148               const cmt_string& file_name,
149               int line_number)
150  {
151    if (use == &(Use::current ())) 
152      {
153        Branch::action (words);
154      }
155  }
156  void action (const CmtSystem::cmt_string_vector& words,
157               Project* project,
158               const cmt_string& file_name,
159               int line_number)
160  {}
161
162};
163
164class KwdBuildStrategy : public Kwd
165{
166public:
167  bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
168  {
169    bool result = true;   
170     
171    value =  w; 
172   
173    /*Symbol* symbol = Symbol::find ("use_strategy");
174      if (symbol != 0)
175      {
176      cmt_string s = symbol->build_macro_value ();
177      Symbol::expand (s);
178      cerr <<"# value s: "<<s<<endl;     
179      } */ 
180
181    Symbol::expand(value);
182    //cerr <<"# value: "<<value<<endl;
183   
184    if (value == "prototypes")
185      {
186        strategy = "BuildPrototypes";
187      }
188    else if (value == "no_prototypes")
189      {
190        strategy = "BuildPrototypes";
191      }
192    else if ((value == "with_installarea") || (value == "with_install_area"))
193      {
194        value = "with_installarea";
195        strategy = "InstallArea";
196      }
197    else if ((value == "without_installarea") || (value == "without_install_area"))
198      {
199        value = "without_installarea";
200        strategy = "InstallArea";
201      }
202    else
203      {
204        result = false;
205      }
206
207    return (result);
208  }
209
210  void action (const CmtSystem::cmt_string_vector& words,
211               Use* use,
212               const cmt_string& file_name,
213               int line_number)
214  {
215    /*       
216    cmt_string cmtpath;
217    cmt_string offset;
218
219    use->get_cmtpath_and_offset (cmtpath, offset);
220
221    Project* p = Project::find_by_cmtpath (cmtpath);
222    */
223    Project* p = const_cast<Project*>(use->get_project ());
224    //    const Project* p = use->get_project ();
225
226    for (int i = 1; i < words.size (); i++)
227      {
228        const cmt_string& w = words[i];
229
230        cmt_string strategy;
231        cmt_string value;
232
233        bool in_error = false;
234
235        if (decode (w, strategy, value))
236          {
237                   
238            if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
239          }
240        else
241          {
242            in_error = true;
243
244            CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
245          }
246      }
247  }
248
249  void action (const CmtSystem::cmt_string_vector& words,
250               Project* project,
251               const cmt_string& file_name,
252               int line_number)
253  {
254    // action (words, project->get_use(), file_name, line_number);
255    // cerr << project->get_use()->get_strategy ("InstallArea") << endl;   
256 
257           
258    for (int i = 1; i < words.size (); i++)
259      {
260        const cmt_string& w = words[i];
261
262        cmt_string strategy;
263        cmt_string value;
264
265        bool in_error = false;
266
267        if (decode (w, strategy, value))
268          {
269            if (project != 0) 
270              {
271                // project->set_strategy (strategy, value, project->get_use()->get_package_name ());
272                project->set_strategy (strategy, value, "");
273                cmt_string s  = "build_strategy ";
274                s += words[i];
275                s += "\n";           
276                bool no_found = true;                   
277                int size =  project->m_extra_lines.size ();
278                for (int n = 0; n < size; n++)
279                  {
280                    if (s==project->m_extra_lines[n])
281                      no_found = false;
282                  }
283                if (no_found)         
284                  { 
285                    cmt_string & buffer = project->m_extra_lines.add();           
286                    buffer = s;
287                  }
288              } 
289          }
290        else
291          {
292            in_error = true;
293            char num[32]; sprintf (num, "%d", line_number);
294            CmtError::set (CmtError::syntax_error,
295                           project->get_name ()
296                           + " project file: " + file_name
297                           + ": line: " + num
298                           + ": " + value + ": Bad strategy value");
299            //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
300          }
301      }
302  }
303};
304
305class KwdCleanupScript : public Kwd
306{
307public:
308  void action (const CmtSystem::cmt_string_vector& words,
309               Use* use,
310               const cmt_string& file_name,
311               int line_number)
312  {
313    Script::action (words, CleanupScript, use);
314    Symbol::action (words, CommandCleanupScript, use);
315  }
316  void action (const CmtSystem::cmt_string_vector& words,
317               Project* project,
318               const cmt_string& file_name,
319               int line_number)
320  {}
321};
322
323class KwdCmtPathPattern : public Kwd
324{
325public:
326  void action (const CmtSystem::cmt_string_vector& words,
327               Use* use,
328               const cmt_string& /*file_name*/,
329               int /*line_number*/)
330  {
331    CmtPathPattern::action (words, use);
332  }
333  void action (const CmtSystem::cmt_string_vector& words,
334               Project* project,
335               const cmt_string& file_name,
336               int line_number)
337  {}
338
339};
340
341class KwdCmtPathPatternRevert : public Kwd
342{
343public:
344  void action (const CmtSystem::cmt_string_vector& words,
345               Use* use,
346               const cmt_string& /*file_name*/,
347               int /*line_number*/)
348  {
349    CmtPathPattern::action (words, use, true);
350  }
351
352  void action (const CmtSystem::cmt_string_vector& words,
353               Project* project,
354               const cmt_string& file_name,
355               int line_number)
356  {}
357};
358
359class KwdContainer : public Kwd
360{
361public:
362  void action (const CmtSystem::cmt_string_vector& words,
363               Use* use,
364               const cmt_string& file_name,
365               int line_number)
366  {
367  }
368
369  void action (const CmtSystem::cmt_string_vector& words,
370               Project* project,
371               const cmt_string& file_name,
372               int line_number)
373  {
374    project->container_action (words);
375    //project->container_action (words[1], words[2]);
376  }
377};
378
379class KwdDocument : public Kwd
380{
381public:
382  void action (const CmtSystem::cmt_string_vector& words,
383               Use* use,
384               const cmt_string& file_name,
385               int line_number)
386  {
387    if (use == &(Use::current ()))
388      {
389        Constituent::action (Document, words);
390      }
391  }
392  void action (const CmtSystem::cmt_string_vector& words,
393               Project* project,
394               const cmt_string& file_name,
395               int line_number)
396  {}
397
398};
399
400class KwdEndPrivate : public Kwd
401{
402public:
403  void action (const CmtSystem::cmt_string_vector& words,
404               Use* use,
405               const cmt_string& file_name,
406               int line_number)
407  {
408    if (use != &(Use::current ()))
409      {
410        use->pop_scope_section ();
411      }
412  }
413  void action (const CmtSystem::cmt_string_vector& words,
414               Project* project,
415               const cmt_string& file_name,
416               int line_number)
417  {}
418};
419
420class KwdEndPublic : public Kwd
421{
422public:
423  void action (const CmtSystem::cmt_string_vector& words,
424               Use* use,
425               const cmt_string& file_name,
426               int line_number)
427  {
428    if (use != &(Use::current ()))
429      {
430        use->pop_scope_section ();
431      }
432  }
433  void action (const CmtSystem::cmt_string_vector& words,
434               Project* project,
435               const cmt_string& file_name,
436               int line_number)
437  {}
438};
439
440class KwdIgnorePattern : public Kwd
441{
442public:
443  void action (const CmtSystem::cmt_string_vector& words,
444               Use* use,
445               const cmt_string& file_name,
446               int line_number)
447  {
448    IgnorePattern::action (words, use);
449  }
450  void action (const CmtSystem::cmt_string_vector& words,
451               Project* project,
452               const cmt_string& file_name,
453               int line_number)
454  {}
455
456};
457
458class KwdIncludeDirs : public Kwd
459{
460public:
461  void action (const CmtSystem::cmt_string_vector& words,
462               Use* use,
463               const cmt_string& file_name,
464               int line_number)
465  {
466    Include::action (words, use);
467  }
468  void action (const CmtSystem::cmt_string_vector& words,
469               Project* project,
470               const cmt_string& file_name,
471               int line_number)
472  {}
473
474};
475
476class KwdIncludePath : public Kwd
477{
478public:
479  void action (const CmtSystem::cmt_string_vector& words,
480               Use* use,
481               const cmt_string& file_name,
482               int line_number)
483  {
484    if (words.size () > 1)
485      {
486        use->set_include_path (words[1]);
487      }
488  }
489  void action (const CmtSystem::cmt_string_vector& words,
490               Project* project,
491               const cmt_string& file_name,
492               int line_number)
493  {}
494
495};
496
497class KwdLanguage : public Kwd
498{
499public:
500  void action (const CmtSystem::cmt_string_vector& words,
501               Use* use,
502               const cmt_string& file_name,
503               int line_number)
504  {
505    Language::action (words, use);
506  }
507  void action (const CmtSystem::cmt_string_vector& words,
508               Project* project,
509               const cmt_string& file_name,
510               int line_number)
511  {}
512
513};
514
515class KwdLibrary : public Kwd
516{
517public:
518  void action (const CmtSystem::cmt_string_vector& words,
519               Use* use,
520               const cmt_string& file_name,
521               int line_number)
522  {
523    if (use == &(Use::current ()))
524      {
525        Constituent::action (Library, words);
526      }
527  }
528  void action (const CmtSystem::cmt_string_vector& words,
529               Project* project,
530               const cmt_string& file_name,
531               int line_number)
532  {}
533};
534
535class KwdMacro : public Kwd
536{
537public:
538  void action (const CmtSystem::cmt_string_vector& words,
539               Use* use,
540               const cmt_string& file_name,
541               int line_number)
542  {
543    Symbol::action (words, CommandMacro, use);
544  }
545  void action (const CmtSystem::cmt_string_vector& words,
546               Project* project,
547               const cmt_string& file_name,
548               int line_number)
549  {
550    action (words, project->get_use(), file_name, line_number);   
551  }
552};
553
554class KwdMacroPrepend : public Kwd
555{
556public:
557  void action (const CmtSystem::cmt_string_vector& words,
558               Use* use,
559               const cmt_string& file_name,
560               int line_number)
561  {
562    Symbol::action (words, CommandMacroPrepend, use);
563  }
564  void action (const CmtSystem::cmt_string_vector& words,
565               Project* project,
566               const cmt_string& file_name,
567               int line_number)
568  {
569    action (words, project->get_use(), file_name, line_number);
570  }
571};
572
573class KwdMacroAppend : public Kwd
574{
575public:
576  void action (const CmtSystem::cmt_string_vector& words,
577               Use* use,
578               const cmt_string& file_name,
579               int line_number)
580  {
581    Symbol::action (words, CommandMacroAppend, use);
582  }
583  void action (const CmtSystem::cmt_string_vector& words,
584               Project* project,
585               const cmt_string& file_name,
586               int line_number)
587  {
588    action (words, project->get_use(), file_name, line_number);
589  }
590};
591
592class KwdMacroRemove : public Kwd
593{
594public:
595  void action (const CmtSystem::cmt_string_vector& words,
596               Use* use,
597               const cmt_string& file_name,
598               int line_number)
599  {
600    Symbol::action (words, CommandMacroRemove, use);
601  }
602  void action (const CmtSystem::cmt_string_vector& words,
603               Project* project,
604               const cmt_string& file_name,
605               int line_number)
606  {
607    action (words, project->get_use(), file_name, line_number);
608  }
609};
610
611class KwdMacroRemoveRegexp : public Kwd
612{
613public:
614  void action (const CmtSystem::cmt_string_vector& words,
615               Use* use,
616               const cmt_string& file_name,
617               int line_number)
618  {
619    Symbol::action (words, CommandMacroRemoveRegexp, use);
620  }
621  void action (const CmtSystem::cmt_string_vector& words,
622               Project* project,
623               const cmt_string& file_name,
624               int line_number)
625 
626  {
627    action (words, project->get_use(), file_name, line_number);
628  }
629};
630
631class KwdMacroRemoveAll : public Kwd
632{
633public:
634  void action (const CmtSystem::cmt_string_vector& words,
635               Use* use,
636               const cmt_string& file_name,
637               int line_number)
638  {
639    Symbol::action (words, CommandMacroRemoveAll, use);
640  }
641  void action (const CmtSystem::cmt_string_vector& words,
642               Project* project,
643               const cmt_string& file_name,
644               int line_number)
645  {
646    action (words, project->get_use(), file_name, line_number);
647  }
648};
649
650class KwdMacroRemoveAllRegexp : public Kwd
651{
652public:
653  void action (const CmtSystem::cmt_string_vector& words,
654               Use* use,
655               const cmt_string& file_name,
656               int line_number)
657  {
658    Symbol::action (words, CommandMacroRemoveAllRegexp, use);
659  }
660  void action (const CmtSystem::cmt_string_vector& words,
661               Project* project,
662               const cmt_string& file_name,
663               int line_number)
664  {
665    action (words, project->get_use(), file_name, line_number);
666  }
667};
668
669class KwdMakeFragment : public Kwd
670{
671public:
672  void action (const CmtSystem::cmt_string_vector& words,
673               Use* use,
674               const cmt_string& file_name,
675               int line_number)
676  {
677    Fragment::action (words, use);
678  }
679  void action (const CmtSystem::cmt_string_vector& words,
680               Project* project,
681               const cmt_string& file_name,
682               int line_number)
683  {}
684};
685
686class KwdManager : public Kwd
687{
688public:
689  void action (const CmtSystem::cmt_string_vector& words,
690               Use* use,
691               const cmt_string& file_name,
692               int line_number)
693  {
694    use->manager_action (words);
695  }
696  void action (const CmtSystem::cmt_string_vector& words,
697               Project* project,
698               const cmt_string& file_name,
699               int line_number)
700  {}
701};
702
703class KwdPackage : public Kwd
704{
705public:
706  void action (const CmtSystem::cmt_string_vector& words,
707               Use* use,
708               const cmt_string& file_name,
709               int line_number)
710  {
711    /*
712      if (words.size () > 1)
713      {
714      if (use == &(Use::current()))
715      {
716      m_current_package = words[1];
717      build_prefix (m_current_package, m_current_prefix);
718           
719      if ((use->get_package_name () != "") &&
720      (use->get_package_name () != m_current_package))
721      {
722      if (!m_quiet)
723      {
724      //  cerr << "#CMT> package name mismatch in requirements of " <<
725      //  use->get_package_name () << " " <<
726      //  use->version << " line #" << line_number;
727      //  cerr << " : " << m_current_package << " versus " <<
728      //  use->get_package_name () << endl;
729      }
730      }
731           
732      use->set (m_current_package,
733      m_current_version,
734      m_current_path,
735      "",
736      "");
737           
738      use->change_path (m_current_path);
739      use->style = m_current_style;
740      }
741      }
742    */
743  }
744  void action (const CmtSystem::cmt_string_vector& words,
745               Project* project,
746               const cmt_string& file_name,
747               int line_number)
748  {}
749};
750
751class KwdPath : public Kwd
752{
753public:
754  void action (const CmtSystem::cmt_string_vector& words,
755               Use* use,
756               const cmt_string& file_name,
757               int line_number)
758  {
759    Symbol::action (words, CommandPath, use);
760  }
761  void action (const CmtSystem::cmt_string_vector& words,
762               Project* project,
763               const cmt_string& file_name,
764               int line_number)
765  {}
766
767};
768
769class KwdPathAppend : public Kwd
770{
771public:
772  void action (const CmtSystem::cmt_string_vector& words,
773               Use* use,
774               const cmt_string& file_name,
775               int line_number)
776  {
777    Symbol::action (words, CommandPathAppend, use);
778  }
779  void action (const CmtSystem::cmt_string_vector& words,
780               Project* project,
781               const cmt_string& file_name,
782               int line_number)
783  {}
784};
785
786class KwdPathPrepend : public Kwd
787{
788public:
789  void action (const CmtSystem::cmt_string_vector& words,
790               Use* use,
791               const cmt_string& file_name,
792               int line_number)
793  {
794    Symbol::action (words, CommandPathPrepend, use);
795  }
796  void action (const CmtSystem::cmt_string_vector& words,
797               Project* project,
798               const cmt_string& file_name,
799               int line_number)
800  {}
801};
802 
803class KwdPathRemove : public Kwd
804{
805public:
806  void action (const CmtSystem::cmt_string_vector& words,
807               Use* use,
808               const cmt_string& file_name,
809               int line_number)
810  {
811    Symbol::action (words, CommandPathRemove, use);
812  }
813  void action (const CmtSystem::cmt_string_vector& words,
814               Project* project,
815               const cmt_string& file_name,
816               int line_number)
817  {} 
818};
819
820class KwdPathRemoveRegexp : public Kwd
821{
822public:
823  void action (const CmtSystem::cmt_string_vector& words,
824               Use* use,
825               const cmt_string& file_name,
826               int line_number)
827  {
828    Symbol::action (words, CommandPathRemoveRegexp, use);
829  }
830  void action (const CmtSystem::cmt_string_vector& words,
831               Project* project,
832               const cmt_string& file_name,
833               int line_number)
834  {} 
835};
836
837class KwdPattern : public Kwd
838{
839public:
840  void action (const CmtSystem::cmt_string_vector& words,
841               Use* use,
842               const cmt_string& file_name,
843               int line_number)
844  {
845    Pattern::action (words, use);
846  }
847  void action (const CmtSystem::cmt_string_vector& words,
848               Project* project,
849               const cmt_string& file_name,
850               int line_number)
851  {}   
852};
853
854class KwdPrivate : public Kwd
855{
856public:
857  void action (const CmtSystem::cmt_string_vector& words,
858               Use* use,
859               const cmt_string& file_name,
860               int line_number)
861  {
862    if (use != &(Use::current ()))
863      {
864        use->push_scope_section (ScopePrivate);
865      }
866  }
867  void action (const CmtSystem::cmt_string_vector& words,
868               Project* project,
869               const cmt_string& file_name,
870               int line_number)
871  {} 
872};
873
874class KwdProject : public Kwd
875{
876public:
877  void action (const CmtSystem::cmt_string_vector& words,
878               Use* use,
879               const cmt_string& file_name,
880               int line_number)
881  {
882  }
883
884  void action (const CmtSystem::cmt_string_vector& words,
885               Project* project,
886               const cmt_string& file_name,
887               int line_number)
888  {
889  } 
890};
891
892class KwdPublic : public Kwd
893{
894public:
895  void action (const CmtSystem::cmt_string_vector& words,
896               Use* use,
897               const cmt_string& file_name,
898               int line_number)
899  {
900    if (use != &(Use::current ()))
901      {
902        use->push_scope_section (ScopePublic);
903      }
904  }
905  void action (const CmtSystem::cmt_string_vector& words,
906               Project* project,
907               const cmt_string& file_name,
908               int line_number)
909  {}   
910};
911
912class KwdSet : public Kwd
913{
914public:
915  void action (const CmtSystem::cmt_string_vector& words,
916               Use* use,
917               const cmt_string& file_name,
918               int line_number)
919  {
920    Symbol::action (words, CommandSet, use);
921  }
922  void action (const CmtSystem::cmt_string_vector& words,
923               Project* project,
924               const cmt_string& file_name,
925               int line_number)
926  {}   
927};
928
929class KwdSetAppend : public Kwd
930{
931public:
932  void action (const CmtSystem::cmt_string_vector& words,
933               Use* use,
934               const cmt_string& file_name,
935               int line_number)
936  {
937    Symbol::action (words, CommandSetAppend, use);
938  }
939  void action (const CmtSystem::cmt_string_vector& words,
940               Project* project,
941               const cmt_string& file_name,
942               int line_number)
943  {}   
944};
945
946class KwdSetPrepend : public Kwd
947{
948public:
949  void action (const CmtSystem::cmt_string_vector& words,
950               Use* use,
951               const cmt_string& file_name,
952               int line_number)
953  {
954    Symbol::action (words, CommandSetPrepend, use);
955  }
956  void action (const CmtSystem::cmt_string_vector& words,
957               Project* project,
958               const cmt_string& file_name,
959               int line_number)
960  {}   
961};
962
963class KwdSetRemove : public Kwd
964{
965public:
966  void action (const CmtSystem::cmt_string_vector& words,
967               Use* use,
968               const cmt_string& file_name,
969               int line_number)
970  {
971    Symbol::action (words, CommandSetRemove, use);
972  }
973  void action (const CmtSystem::cmt_string_vector& words,
974               Project* project,
975               const cmt_string& file_name,
976               int line_number)
977  {}   
978};
979
980class KwdSetRemoveRegexp : public Kwd
981{
982public:
983  void action (const CmtSystem::cmt_string_vector& words,
984               Use* use,
985               const cmt_string& file_name,
986               int line_number)
987  {
988    Symbol::action (words, CommandSetRemoveRegexp, use);
989  }
990  void action (const CmtSystem::cmt_string_vector& words,
991               Project* project,
992               const cmt_string& file_name,
993               int line_number)
994  {} 
995};
996
997class KwdSetupScript : public Kwd
998{
999public:
1000  void action (const CmtSystem::cmt_string_vector& words,
1001               Use* use,
1002               const cmt_string& file_name,
1003               int line_number)
1004  {
1005    Script::action (words, SetupScript, use);
1006    Symbol::action (words, CommandSetupScript, use);
1007  }
1008  void action (const CmtSystem::cmt_string_vector& words,
1009               Project* project,
1010               const cmt_string& file_name,
1011               int line_number)
1012  {}
1013};
1014
1015class KwdSetupStrategy : public Kwd
1016{
1017public:
1018  bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
1019  {
1020    bool result = true;
1021
1022    value =  w; 
1023    Symbol::expand(value);
1024
1025
1026    if (value == "config")
1027      {
1028        strategy = "SetupConfig";
1029      }
1030    else if (value == "no_config")
1031      {
1032        strategy = "SetupConfig";
1033      }
1034    else if (value == "root")
1035      {
1036        strategy = "SetupRoot";
1037      }
1038    else if (value == "no_root")
1039      {
1040        strategy = "SetupRoot";
1041      }
1042    else if (value == "cleanup")
1043      {
1044        strategy = "SetupCleanup";
1045      }
1046    else if (value == "no_cleanup")
1047      {
1048        strategy = "SetupCleanup";
1049      }
1050    else if (value == "scripts")
1051      {
1052        strategy = "SetupScripts";
1053      }
1054    else if (value == "no_scripts")
1055      {
1056        strategy = "SetupScripts";
1057      }
1058    else
1059      {
1060        result = false;
1061      }
1062
1063    return (result);
1064  }
1065
1066  void action (const CmtSystem::cmt_string_vector& words,
1067               Use* use,
1068               const cmt_string& file_name,
1069               int line_number)
1070  {
1071    /*
1072    cmt_string cmtpath;
1073    cmt_string offset;
1074
1075    use->get_cmtpath_and_offset (cmtpath, offset);
1076
1077    Project* p = Project::find_by_cmtpath (cmtpath);
1078    */
1079    Project* p = const_cast<Project*>(use->get_project ());
1080    //    const Project* p = use->get_project ();
1081
1082    for (int i = 1; i < words.size (); i++)
1083      {
1084        const cmt_string& w = words[i];
1085
1086        cmt_string strategy;
1087        cmt_string value;
1088
1089        bool in_error = false;
1090
1091        if (decode (w, strategy, value))
1092          {
1093            if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
1094          }
1095        else
1096          {
1097            in_error = true;
1098
1099            CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
1100          }
1101      }
1102  }
1103
1104  void action (const CmtSystem::cmt_string_vector& words,
1105               Project* project,
1106               const cmt_string& file_name,
1107               int line_number)
1108  {
1109    for (int i = 1; i < words.size (); i++)
1110      {
1111        const cmt_string& w = words[i];
1112
1113        cmt_string strategy;
1114        cmt_string value;
1115
1116        bool in_error = false;
1117
1118        if (decode (w, strategy, value))
1119          {
1120            if (project != 0) project->set_strategy (strategy, value, "");
1121            cmt_string s  = "setup_strategy ";
1122            s += words[i];
1123            s += "\n";
1124
1125            bool no_found = true;                       
1126            int size =  project->m_extra_lines.size ();
1127            for (int n = 0; n < size; n++)
1128              {
1129                if (s==project->m_extra_lines[n])
1130                  no_found = false;
1131              }
1132            if (no_found)         
1133              { 
1134                cmt_string & buffer = project->m_extra_lines.add();           
1135                buffer = s;
1136              }
1137          }
1138        else
1139          {
1140            in_error = true;
1141            char num[32]; sprintf (num, "%d", line_number);
1142            CmtError::set (CmtError::syntax_error,
1143                           project->get_name ()
1144                           + " project file: " + file_name
1145                           + ": line: " + num
1146                           + ": " + value + ": Bad strategy value");
1147            //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
1148          }
1149      }
1150  }
1151};
1152
1153class KwdStructureStrategy : public Kwd
1154{
1155public:
1156  bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
1157  {
1158    bool result = true;
1159
1160    value = w;
1161    Symbol::expand(value);
1162
1163    if (value == "with_version_directory")
1164      {
1165        strategy = "VersionDirectory";
1166      }
1167    else if (value == "without_version_directory")
1168      {
1169        strategy = "VersionDirectory";
1170      }
1171    else
1172      {
1173        result = false;
1174      }
1175
1176    return (result);
1177  }
1178
1179  void action (const CmtSystem::cmt_string_vector& words,
1180               Use* use,
1181               const cmt_string& file_name,
1182               int line_number)
1183  {
1184    /*
1185    cmt_string cmtpath;
1186    cmt_string offset;
1187
1188    use->get_cmtpath_and_offset (cmtpath, offset);
1189
1190    Project* p = Project::find_by_cmtpath (cmtpath);
1191    */
1192    Project* p = const_cast<Project*>(use->get_project ());
1193    //    const Project* p = use->get_project ();
1194
1195    for (int i = 1; i < words.size (); i++)
1196      {
1197        const cmt_string& w = words[i];
1198
1199        cmt_string strategy;
1200        cmt_string value;
1201
1202        bool in_error = false;
1203
1204        if (decode (w, strategy, value))
1205          {
1206            if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
1207          }
1208        else
1209          {
1210            in_error = true;
1211
1212            CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
1213          }
1214      }
1215  }
1216
1217  void action (const CmtSystem::cmt_string_vector& words,
1218               Project* project,
1219               const cmt_string& file_name,
1220               int line_number)
1221  {
1222    for (int i = 1; i < words.size (); i++)
1223      {
1224        const cmt_string& w = words[i];
1225
1226        cmt_string strategy;
1227        cmt_string value;
1228
1229        bool in_error = false;
1230
1231        if (decode (w, strategy, value))
1232          {
1233            if (project != 0) project->set_strategy (strategy, value, "");
1234            cmt_string s  = "structure_strategy ";
1235            s += words[i];
1236            s += "\n";           
1237
1238            bool no_found = true;                       
1239            int size =  project->m_extra_lines.size ();
1240            for (int n = 0; n < size; n++)
1241              {
1242                if (s == project->m_extra_lines[n])
1243                  no_found = false;
1244              }
1245
1246            if (no_found)         
1247              { 
1248                cmt_string & buffer = project->m_extra_lines.add();           
1249                buffer = s;
1250              }     
1251          }
1252        else
1253          {
1254            in_error = true;
1255            char num[32]; sprintf (num, "%d", line_number);
1256            CmtError::set (CmtError::syntax_error,
1257                           project->get_name ()
1258                           + " project file: " + file_name
1259                           + ": line: " + num
1260                           + ": " + value + ": Bad strategy value");
1261            //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
1262          }
1263      }
1264  }
1265};
1266
1267class KwdTag : public Kwd
1268{
1269public:
1270  void action (const CmtSystem::cmt_string_vector& words,
1271               Use* use,
1272               const cmt_string& file_name,
1273               int line_number)
1274  {
1275    Tag::action (words, use);
1276  }
1277  void action (const CmtSystem::cmt_string_vector& words,
1278               Project* project,
1279               const cmt_string& file_name,
1280               int line_number)
1281  {
1282    action (words, project->get_use(), file_name, line_number);   
1283  } 
1284};
1285
1286class KwdTagExclude : public Kwd
1287{
1288public:
1289  void action (const CmtSystem::cmt_string_vector& words,
1290               Use* use,
1291               const cmt_string& file_name,
1292               int line_number)
1293  {
1294    Tag::action_exclude (words, use);
1295  }
1296  void action (const CmtSystem::cmt_string_vector& words,
1297               Project* project,
1298               const cmt_string& file_name,
1299               int line_number)
1300  {
1301    action (words, project->get_use(), file_name, line_number);   
1302  } 
1303};
1304
1305class KwdUse : public Kwd
1306{
1307public:
1308  void action (const CmtSystem::cmt_string_vector& words,
1309               Use* use,
1310               const cmt_string& file_name,
1311               int line_number)
1312  {
1313    Use::action (words, use);
1314  }
1315
1316  void action (const CmtSystem::cmt_string_vector& words,
1317               Project* project,
1318               const cmt_string& file_name,
1319               int line_number)
1320  {
1321    project->use_action (words[1], words[2]);
1322  }
1323};
1324
1325class KwdVersionStrategy : public Kwd
1326{
1327public:
1328  void action (const CmtSystem::cmt_string_vector& words,
1329               Use* use,
1330               const cmt_string& file_name,
1331               int line_number)
1332  {
1333    CmtMessage::warning ("Package " + use->get_package_name ()
1334                         + " sets obsolescent version strategy");
1335    //    cerr << "# Package " << use->get_package_name () <<
1336    //      " sets obsolescent version strategy" << endl;
1337  }
1338  void action (const CmtSystem::cmt_string_vector& words,
1339               Project* project,
1340               const cmt_string& file_name,
1341               int line_number)
1342  {}
1343};
1344
1345class KwdVersion : public Kwd
1346{
1347public:
1348  void action (const CmtSystem::cmt_string_vector& words,
1349               Use* use,
1350               const cmt_string& file_name,
1351               int line_number)
1352  {
1353  }
1354  void action (const CmtSystem::cmt_string_vector& words,
1355               Project* project,
1356               const cmt_string& file_name,
1357               int line_number)
1358  {}
1359};
1360
1361class KwdDefault : public Kwd
1362{
1363public:
1364  void action (const CmtSystem::cmt_string_vector& words,
1365               Use* use,
1366               const cmt_string& file_name,
1367               int line_number)
1368  {
1369    /*
1370      Unknown keyword : just ignore the line
1371    */
1372    char num[32]; sprintf (num, "%d", line_number);
1373    CmtMessage::error ("bad syntax in requirements of " + use->get_package_name ()
1374                       + " " + use->version + " line #" + num
1375                       + " [" + words[0] + "...]");
1376    /*
1377    if (!Cmt::get_quiet ())
1378      {
1379        cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
1380             << " " << use->version << " line #" << line_number;
1381        cerr << " [" << words[0] << "...]" << endl;
1382      }
1383    */
1384   
1385    CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
1386  }
1387 
1388  void action (const CmtSystem::cmt_string_vector& words,
1389               Project* project,
1390               const cmt_string& file_name,
1391               int line_number)
1392  {action (words, project->get_use(), file_name, line_number);}
1393};
1394
1395SyntaxParser& SyntaxParser::instance ()
1396{
1397  static SyntaxParser p;
1398
1399  return (p);
1400}
1401
1402/**
1403 *  Parse the input file, rejecting comments and
1404 * rebuilding complete lines (from sections separated by
1405 *  \\ characters.
1406 *
1407 *  Each reformatted line is parsed by filter_line
1408 */
1409void SyntaxParser::parse_requirements (const cmt_string& file_name, Use* use)
1410{
1411  SyntaxParser& me = instance ();
1412
1413  if (use != 0)
1414    {
1415      cmt_string buffer;
1416
1417      use->fill_standard_macros (buffer);
1418
1419      AccessMode saved_current_access = Cmt::get_current_access ();
1420      Cmt::set_current_access (UserMode);
1421      me.do_parse_text (buffer, "", package_context, use, 0);
1422      Cmt::set_current_access (saved_current_access);
1423    }
1424
1425  me.do_parse_requirements (file_name, use);
1426 
1427 
1428  if (use != 0)
1429    {
1430      //
1431     
1432      const Project* p = use->get_project ();
1433      if (p != 0)
1434        {     
1435          Use* p_use =  p->get_use();
1436          if (p_use != 0 && p_use != use)
1437            {
1438             
1439              //{
1440              //  int  size  = use->sub_uses.size ();
1441              //  for (int n = 0; n < size; n++)
1442              //  {
1443              //      Use* tuse = use->sub_uses[n];
1444              //      cerr << "\tpackage file [" << tuse->get_package_name() << "]" <<p_use->get_package_name()<< endl;         
1445              //  }
1446              //}
1447             
1448              // add the dependency
1449              use->add_sub_use (p_use);
1450             
1451              // add the right extra statements
1452              {
1453                int size =  p->m_extra_lines.size ();
1454                for (int n = 0; n < size; n++)
1455                  {
1456                    cmt_string& s = p->m_extra_lines[n];
1457                    SyntaxParser::parse_requirements_line (s, use);
1458                  } 
1459              } 
1460             
1461              // Fill other values               
1462              use->sub_use_scopes.push_back (use->get_current_scope ());
1463              use->sub_use_auto_imports.push_back (p_use->auto_imports);
1464              // cmt_string& request = use->requests.add ();                                         
1465              // request = package_name;
1466              // request += " ";
1467              // request += version;
1468              // request += " ";
1469              // request += path;
1470             
1471              // add at the uses level ?????
1472              static Use::UsePtrVector& uses = Use::get_ordered_uses ();
1473              //const Use& cu = Use::current ();
1474             
1475              bool found = false;
1476              int  size  = uses.size ();
1477             
1478              // cerr << "\n size:"<<size<< ":" << endl;     
1479              for (int n = 0; n < size; n++)
1480                {
1481                  Use* tuse = uses[n];
1482                  // cerr << "\tpackage file [" << tuse->get_package_name() << "]" <<p_use->get_package_name()<< endl;                   
1483                  if (tuse->get_package_name()==p_use->get_package_name())
1484                    found=true;
1485                }   
1486              if (! found)
1487                {
1488                  uses.push_back (p_use);
1489                  p_use->m_index = uses.size () - 1;
1490                }
1491             
1492            }
1493          // Apply tag container_package if
1494          // the current package is the container package of the project
1495          if (use == &(Use::current ()) &&
1496              use->get_package_name() == p->get_container ().get_package_name () &&
1497              use->version == p->get_container ().version)
1498            {
1499              cmt_string name ("container_package");
1500              cmt_string context (p->get_name ());
1501              Tag* tag = Tag::find (name);
1502              if (tag == 0)
1503                {
1504                  tag = Tag::add (name, PriorityUserTag, context, use);
1505                }
1506              tag->mark (use->get_package_name());
1507            }
1508        }                 
1509      use->close_scope_sections ();
1510    }
1511}
1512
1513/**
1514 */
1515void SyntaxParser::parse_project_file_text (const cmt_string& text,
1516                                            const cmt_string& file_name,
1517                                            Project* project)
1518{
1519  SyntaxParser& me = instance ();
1520  me.do_parse_text (text, file_name, project_context, 0, project);
1521}
1522
1523/**
1524 *  Parse a text, rejecting comments and
1525 * rebuilding complete lines (from sections separated by
1526 *  \\ characters.
1527 *
1528 *  Each reformatted line is parsed by filter_line
1529 */
1530void SyntaxParser::parse_requirements_text (const cmt_string& text,
1531                                            const cmt_string& file_name,
1532                                            Use* use)
1533{
1534  SyntaxParser& me = instance ();
1535
1536  /**
1537   *
1538   *    We have to preserve m_current_access since it reflects whether
1539   *   the current cmt action is run in the context of the current package.
1540   *   (the opposite is when the cmt command specifies the current package
1541   *    in its arguments -use=... therefore the pwd is NOT the directory
1542   *    of the current package)
1543   *
1544   *   m_current_access is Developer when pwd =  current
1545   *                       User      when pwd != current
1546   *
1547   *    Therefore, as soon as we reach a used package, this must be switched to User
1548   *
1549   *   On the other hand, Cmt::scope reflects the status of the public/private
1550   *  statements. By default, we are in public context when entering a new requirements
1551   *  file.
1552   *
1553   */
1554
1555  AccessMode saved_current_access;
1556
1557  saved_current_access = Cmt::get_current_access ();
1558
1559  if (use == 0) use = &(Use::current ());
1560
1561  if (use != &(Use::current ()))
1562    {
1563      if (Cmt::get_debug ())
1564        {
1565          cout << "parse_requirements_text> set UserMode" << endl;
1566        }
1567
1568      Cmt::set_current_access (UserMode);
1569    }
1570  else
1571    {
1572      if (Cmt::get_debug ())
1573        {
1574          cout << "parse_requirements_text> set DeveloperMode" << endl;
1575        }
1576
1577      Cmt::set_current_access (DeveloperMode);
1578    }
1579
1580  me.do_parse_text (text, file_name, package_context, use, 0);
1581
1582  Cmt::set_current_access (saved_current_access);
1583}
1584
1585/**
1586 *  Apply the basic parser to one single line :
1587 *
1588 *   o Append to global text if previous back_slash
1589 *   o Split into words
1590 *   o Apply the generic Select operator
1591 */
1592void SyntaxParser::parse_requirements_line (const cmt_string& line,
1593                                            Use* use,
1594                                            const cmt_string& file_name,
1595                                            int line_number)
1596{
1597  SyntaxParser& me = instance ();
1598  me.do_parse_line (line, file_name, line_number, package_context, use, 0);
1599}
1600
1601SyntaxParser::SyntaxParser ()
1602{
1603  m_keywords.add ("action", new KwdAction ());
1604  m_keywords.add ("alias", new KwdAlias ());
1605  m_keywords.add ("application", new KwdApplication ());
1606  m_keywords.add ("apply_pattern", new KwdApplyPattern ());
1607  m_keywords.add ("apply_tag", new KwdApplyTag ());
1608  m_keywords.add ("author", new KwdAuthor ());
1609  m_keywords.add ("branches", new KwdBranches ());
1610  m_keywords.add ("build_strategy", new KwdBuildStrategy ());
1611  m_keywords.add ("cleanup_script", new KwdCleanupScript ());
1612  m_keywords.add ("cmtpath_pattern", new KwdCmtPathPattern ());
1613  m_keywords.add ("cmtpath_pattern_reverse", new KwdCmtPathPatternRevert ());
1614  m_keywords.add ("document", new KwdDocument ());
1615  m_keywords.add ("end_private", new KwdEndPrivate ());
1616  m_keywords.add ("end_public", new KwdEndPublic ());
1617  m_keywords.add ("ignore_pattern", new KwdIgnorePattern ());
1618  m_keywords.add ("include_dirs", new KwdIncludeDirs ());
1619  m_keywords.add ("include_path", new KwdIncludePath ());
1620  m_keywords.add ("language", new KwdLanguage ());
1621  m_keywords.add ("library", new KwdLibrary ());
1622  m_keywords.add ("macro", new KwdMacro ());
1623  m_keywords.add ("macro+", new KwdMacroAppend ());
1624  m_keywords.add ("macro_prepend", new KwdMacroPrepend ());
1625  m_keywords.add ("macro_append", new KwdMacroAppend ());
1626  m_keywords.add ("macro_remove", new KwdMacroRemove ());
1627  m_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ());
1628  m_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ());
1629  m_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ());
1630  m_keywords.add ("make_fragment", new KwdMakeFragment ());
1631  m_keywords.add ("manager", new KwdManager ());
1632  m_keywords.add ("package", new KwdPackage ());
1633  m_keywords.add ("path", new KwdPath ());
1634  m_keywords.add ("path_append", new KwdPathAppend ());
1635  m_keywords.add ("path_prepend", new KwdPathPrepend ());
1636  m_keywords.add ("path_remove", new KwdPathRemove ());
1637  m_keywords.add ("path_remove_regexp", new KwdPathRemoveRegexp ());
1638  m_keywords.add ("pattern", new KwdPattern ());
1639  m_keywords.add ("public", new KwdPublic ());
1640  m_keywords.add ("private", new KwdPrivate ());
1641  m_keywords.add ("project", new KwdProject ());
1642  m_keywords.add ("set", new KwdSet ());
1643  m_keywords.add ("set_append", new KwdSetAppend ());
1644  m_keywords.add ("set_prepend", new KwdSetPrepend ());
1645  m_keywords.add ("set_remove", new KwdSetRemove ());
1646  m_keywords.add ("set_remove_regexp", new KwdSetRemoveRegexp ());
1647  m_keywords.add ("setup_script", new KwdSetupScript ());
1648  m_keywords.add ("setup_strategy", new KwdSetupStrategy ());
1649  m_keywords.add ("structure_strategy", new KwdStructureStrategy ());
1650  m_keywords.add ("tag", new KwdTag ());
1651  m_keywords.add ("tag_exclude", new KwdTagExclude ());
1652  m_keywords.add ("use", new KwdUse ());
1653  m_keywords.add ("version_strategy", new KwdVersionStrategy ());
1654  m_keywords.add ("version", new KwdVersion ());
1655
1656  m_project_keywords.add ("author", new KwdAuthor());
1657  m_project_keywords.add ("apply_tag", new KwdApplyTag ());
1658  m_project_keywords.add ("build_strategy", new KwdBuildStrategy ());
1659  m_project_keywords.add ("container", new KwdContainer ());
1660  m_project_keywords.add ("macro", new KwdMacro ());
1661  // m_project_keywords.add ("macro+", new KwdMacroAppend ());
1662  // m_project_keywords.add ("macro_prepend", new KwdMacroPrepend ());
1663  // m_project_keywords.add ("macro_append", new KwdMacroAppend ());
1664  //m_project_keywords.add ("macro_remove", new KwdMacroRemove ());
1665  //m_project_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ());
1666  //m_project_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ());
1667  //m_project_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ());
1668
1669  m_project_keywords.add ("project", new KwdProject ());
1670  m_project_keywords.add ("setup_strategy", new KwdSetupStrategy ());
1671 
1672  m_project_keywords.add ("tag", new KwdTag ());
1673  //m_project_keywords.add ("tag_exclude", new KwdTagExclude ());
1674
1675 
1676  m_project_keywords.add ("structure_strategy", new KwdStructureStrategy ());
1677  m_project_keywords.add ("use", new KwdUse ());
1678}
1679
1680void SyntaxParser::do_parse_requirements (const cmt_string& file_name, Use* use)
1681{
1682  cmt_string actual_file_name = file_name;
1683  cmt_string text;
1684
1685  if (CmtError::get_last_error_code () == CmtError::syntax_error)
1686    CmtError::clear ();
1687
1688  if (!CmtSystem::test_file (actual_file_name))
1689    {
1690      actual_file_name = "..";
1691      actual_file_name += CmtSystem::file_separator ();
1692      actual_file_name += "cmt";
1693      actual_file_name += CmtSystem::file_separator ();
1694      actual_file_name += file_name;
1695
1696      if (!CmtSystem::test_file (actual_file_name))
1697        {
1698          actual_file_name = "..";
1699          actual_file_name += CmtSystem::file_separator ();
1700          actual_file_name += "mgr";
1701          actual_file_name += CmtSystem::file_separator ();
1702          actual_file_name += file_name;
1703
1704          if (!CmtSystem::test_file (actual_file_name))
1705            {
1706              return;
1707            }
1708        }
1709    }
1710
1711  if (!text.read (actual_file_name))
1712    {
1713      CmtError::set (CmtError::file_access_error, actual_file_name);
1714      return;
1715    }
1716
1717  SyntaxParser::parse_requirements_text (text, actual_file_name, use);
1718}
1719
1720/**
1721 *  Parse a text, rejecting comments and
1722 * rebuilding complete lines (from sections separated by
1723 *  \\ characters.
1724 *
1725 *  Each reformatted line is parsed by filter_line
1726 */
1727void SyntaxParser::do_parse_text (const cmt_string& text,
1728                                  const cmt_string& file_name,
1729                                  ContextType context,
1730                                  Use* use,
1731                                  Project* project)
1732{
1733  cmt_string line;
1734  int line_number = 1;
1735
1736  if (context == package_context)
1737    {
1738      if (use == 0) use = &(Use::current ());
1739    }
1740
1741  m_filtered_text.erase (0);
1742
1743  int nl;
1744  int begin = 0;
1745  int end = text.size ();
1746
1747  while ((nl = text.find (begin, '\n')) != cmt_string::npos)
1748    {
1749      if (begin < nl && text[nl - 1] == '\r')
1750        {
1751          text.substr (begin, nl - 1 - begin, line);
1752        }
1753      else
1754        {
1755          text.substr (begin, nl - begin, line);
1756        }
1757      //      cerr << "|do_parse_text> [" << line << "]" << endl;
1758      do_parse_line (line, file_name, line_number, context, use, project);
1759      line_number++;
1760      begin = nl + 1;
1761    } // while ((nl = text.find (begin, '\n')) != cmt_string::npos)
1762
1763  if (begin < end)
1764    {
1765      text.substr (begin, end - begin, line);
1766      do_parse_line (line, file_name, line_number, context, use, project);
1767    }
1768
1769}
1770/*
1771void SyntaxParser::do_parse_text (const cmt_string& text,
1772                                  const cmt_string& file_name,
1773                                  ContextType context,
1774                                  Use* use,
1775                                  Project* project)
1776{
1777  cmt_string line;
1778  int pos;
1779  int max_pos;
1780  int line_number = 1;
1781
1782  if (context == package_context)
1783    {
1784      if (use == 0) use = &(Use::current ());
1785    }
1786
1787  m_filtered_text.erase (0);
1788
1789  pos = 0;
1790  max_pos = text.size ();
1791
1792  for (pos = 0; pos < max_pos; )
1793    {
1794      int cr = text.find (pos, "\r\n");
1795      int nl = text.find (pos, '\n');
1796      int first = nl;
1797      int length = 1;
1798
1799      if (cr != cmt_string::npos)
1800        {
1801          if (nl == cmt_string::npos)
1802            {
1803              first = cr;
1804              length = 2;
1805            }
1806          else
1807            {
1808              first = (nl < cr) ? nl : cr;
1809              length = (nl < cr) ? 1 : 2;
1810            }
1811        }
1812
1813      if (first == cmt_string::npos)
1814        {
1815          text.substr (pos, line);
1816          pos = max_pos;
1817        }
1818      else if (first > pos)
1819        {
1820          text.substr (pos, first - pos, line);
1821          pos = first + length;
1822        }
1823      else
1824        {
1825          line.erase (0);
1826          pos += length;
1827        }
1828
1829      do_parse_line (line, file_name, line_number, context, use, project);
1830
1831      if ((Cmt::get_action () == action_check_configuration) && CmtError::has_pending_error ())
1832        {
1833          //break;
1834        }
1835
1836      line_number++;
1837    }
1838}
1839*/
1840
1841void SyntaxParser::do_parse_line (const cmt_string& line,
1842                                  const cmt_string& file_name,
1843                                  int line_number,
1844                                  ContextType context,
1845                                  Use* use,
1846                                  Project* project)
1847{
1848  int length;
1849  int nl;
1850  int back_slash;
1851  cmt_string temp_line = line;
1852
1853  if (temp_line.size () == 0) return;
1854  if (temp_line[0] == '#') return;
1855
1856  nl = temp_line.find_last_of ('\n');
1857  if (nl != cmt_string::npos) temp_line.erase (nl);
1858
1859  length = temp_line.size ();
1860  if (length == 0) return;
1861
1862  //
1863  // We scan the line for handling backslashes.
1864  //
1865  // o Really terminating backslashes (ie those only followed by spaces/tabs
1866  // mean continued line
1867  //
1868  //
1869
1870  bool finished = true;
1871
1872  //  length = temp_line.size ();
1873
1874  back_slash = temp_line.find_last_of ('\\');
1875
1876  if (back_slash != cmt_string::npos)
1877    {
1878      //
1879      // This is the last backslash
1880      // check if there are only space chars after it
1881      //
1882     
1883      bool at_end = true;
1884
1885      for (int i = (back_slash + 1); i < length; i++)
1886        {
1887          char c = temp_line[i];
1888          if ((c != ' ') && (c != '\t'))
1889            {
1890              at_end = false;
1891              break;
1892            }
1893        }
1894
1895      if (at_end)
1896        {
1897          temp_line.erase (back_slash);
1898          finished = false;
1899        }
1900      else
1901        {
1902          // This was not a trailing backslash.
1903          finished = true;
1904        }
1905    }
1906
1907  m_filtered_text += temp_line;
1908
1909  if (!finished)
1910    {
1911      // We still need to accumulate forthcoming lines
1912      // before parsing the resulting text.
1913      return;
1914    }
1915
1916  /*
1917    Here a full line (possibly accumulating several lines
1918    ended by backslashes) is parsed :
1919   
1920    o Special characters are filtered now :
1921   
1922    <cmt:tab/>  \t
1923    <cmt:cr/>   \r
1924    <cmt:lf/>   \n
1925   
1926    o Split into words (a word is a string not containing
1927    spaces or enclosed in quotes)
1928
1929    o Parse the word array (function Select)
1930
1931  */
1932
1933  m_filtered_text.replace_all ("<cmt:tab/>", "\t");
1934  m_filtered_text.replace_all ("<cmt:cr/>",  "\r");
1935  m_filtered_text.replace_all ("<cmt:lf/>",  "\n");
1936
1937  if (Cmt::get_debug ())
1938    {
1939      cout << "parse_requirements_line [" << m_filtered_text << "]" << endl;
1940    }
1941 
1942  static CmtSystem::cmt_string_vector words;
1943 
1944  CmtSystem::split (m_filtered_text, " \t", words);
1945 
1946  if (words.size () != 0)
1947    {
1948      switch (context)
1949        {
1950        case project_context:
1951          do_parse_words (words, file_name, line_number, project);
1952          break;
1953        case package_context:
1954          do_parse_words (words, file_name, line_number, use);
1955          break;
1956        }
1957    }
1958 
1959  m_filtered_text.erase (0);
1960}
1961
1962void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
1963                                   const cmt_string& file_name,
1964                                   int line_number,
1965                                   Use* use)
1966{
1967  if (CmtError::get_last_error_code () == CmtError::syntax_error)
1968        CmtError::clear ();
1969
1970  if (words.size () == 0) return;
1971
1972  const cmt_string& command = words[0];
1973
1974  if (command.size () == 0) return;
1975
1976  //
1977  // First analyze the syntax
1978  //
1979
1980  Kwd* keyword = m_keywords.find (command);
1981  if (keyword == 0)
1982    {
1983      /*
1984
1985      When the first word of the line is not a keyword, it may be an
1986      implicit pattern application.
1987
1988      */
1989
1990      Pattern* p = Pattern::find (command);
1991      if (p == 0)
1992        {
1993          CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
1994        }
1995      else
1996        {
1997          keyword = m_keywords.find ("apply_pattern");
1998        }
1999    }
2000
2001  if (CmtError::get_last_error_code () == CmtError::syntax_error)
2002    //  if (CmtError::has_pending_error ())
2003    {
2004      CmtError::print ();
2005
2006      char num[32]; sprintf (num, "%d", line_number);
2007      CmtMessage::error ("bad syntax in requirements of " + use->get_package_name ()
2008                         + " " + use->version
2009                         + " " + use->specified_path
2010                         + " line #" + num
2011                         + " [" + command + " ...]");
2012      /*
2013      if (!Cmt::get_quiet ())
2014        {
2015          cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
2016               << " " << use->version
2017               << " " << use->specified_path
2018               << " line #" << line_number;
2019          cerr << " [" << command << " ...]" << endl;
2020        }
2021      */
2022
2023      return;
2024    }
2025
2026  //
2027  // Then interpret the action
2028  //
2029
2030  keyword->action (words, use, file_name, line_number);
2031}
2032
2033void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
2034                                   const cmt_string& file_name,
2035                                   int line_number,
2036                                   Project* project)
2037{
2038  if (CmtError::get_last_error_code () == CmtError::syntax_error)
2039    CmtError::clear ();
2040
2041  if (words.size () == 0) return;
2042
2043  const cmt_string& command = words[0];
2044
2045  if (command.size () == 0) return;
2046
2047  //
2048  // First analyze the syntax
2049  //
2050
2051  Kwd* keyword = m_project_keywords.find (command);
2052  if (keyword == 0)
2053    {
2054      CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
2055    }
2056
2057  if (CmtError::get_last_error_code () == CmtError::syntax_error)
2058    //  if (CmtError::has_pending_error ())
2059    {
2060      CmtError::print ();
2061
2062      char num[32]; sprintf (num, "%d", line_number);
2063      CmtMessage::error ("bad syntax in project file of " + project->get_name ()
2064                         + " line #" + num
2065                         + " [" + command + " ...]");
2066      /*
2067      if (!Cmt::get_quiet ())
2068        {
2069          cerr << "#CMT> bad syntax in project file of " << project->get_name ()
2070               << " line #" << line_number;
2071          cerr << " [" << command << " ...]" << endl;
2072        }
2073      */
2074
2075      return;
2076    }
2077
2078  //
2079  // Then interpret the action
2080  //
2081
2082  keyword->action (words, project, file_name, line_number);
2083
2084  if (CmtError::get_last_error_code () == CmtError::syntax_error)
2085    CmtError::print ();
2086}
Note: See TracBrowser for help on using the repository browser.