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

Last change on this file since 272 was 272, checked in by garonne, 18 years ago

See CL 313

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