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

Last change on this file since 663 was 663, checked in by rybkin, 10 years ago

See C.L. 522

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