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

Last change on this file since 634 was 607, checked in by rybkin, 12 years ago

See C.L. 482

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