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

Last change on this file since 467 was 459, checked in by rybkin, 16 years ago

See C.L. 360

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