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

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

See C.L. 511

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