source: CMT/HEAD/source/cmt_syntax.cxx @ 523

Last change on this file since 523 was 523, checked in by rybkin, 15 years ago

See C.L. 410

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