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

Last change on this file since 568 was 568, checked in by rybkin, 13 years ago

See C.L. 451

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