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

Last change on this file since 653 was 653, checked in by rybkin, 11 years ago

See C.L. 512

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