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

Last change on this file since 83 was 83, checked in by arnault, 20 years ago

Add structure_strategy - see CL#278

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