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

Last change on this file since 25 was 19, checked in by arnault, 21 years ago

Accept HEAD as a valid version directory - CL261

  • Property svn:eol-style set to native
File size: 30.7 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 KwdDocument : 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 if (use == &(Use::current ()))
248 {
249 Constituent::action (Document, words);
250 }
251 }
252};
253
254class KwdEndPrivate : public Kwd
255{
256public:
257 void action (const CmtSystem::cmt_string_vector& words,
258 Use* use,
259 const cmt_string& file_name,
260 int line_number)
261 {
262 if (use != &(Use::current ()))
263 {
264 use->pop_scope_section ();
265 }
266 }
267};
268
269class KwdEndPublic : public Kwd
270{
271public:
272 void action (const CmtSystem::cmt_string_vector& words,
273 Use* use,
274 const cmt_string& file_name,
275 int line_number)
276 {
277 if (use != &(Use::current ()))
278 {
279 use->pop_scope_section ();
280 }
281 }
282};
283
284class KwdIgnorePattern : public Kwd
285{
286public:
287 void action (const CmtSystem::cmt_string_vector& words,
288 Use* use,
289 const cmt_string& file_name,
290 int line_number)
291 {
292 IgnorePattern::action (words, use);
293 }
294};
295
296class KwdIncludeDirs : 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 Include::action (words, use);
305 }
306};
307
308class KwdIncludePath : public Kwd
309{
310public:
311 void action (const CmtSystem::cmt_string_vector& words,
312 Use* use,
313 const cmt_string& file_name,
314 int line_number)
315 {
316 if (words.size () > 1)
317 {
318 use->set_include_path (words[1]);
319 }
320 }
321};
322
323class KwdLanguage : public Kwd
324{
325public:
326 void action (const CmtSystem::cmt_string_vector& words,
327 Use* use,
328 const cmt_string& file_name,
329 int line_number)
330 {
331 Language::action (words);
332 }
333};
334
335class KwdLibrary : public Kwd
336{
337public:
338 void action (const CmtSystem::cmt_string_vector& words,
339 Use* use,
340 const cmt_string& file_name,
341 int line_number)
342 {
343 if (use == &(Use::current ()))
344 {
345 Constituent::action (Library, words);
346 }
347 }
348};
349
350class KwdMacro : 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 Symbol::action (words, CommandMacro, use);
359 }
360};
361
362class KwdMacroPrepend : public Kwd
363{
364public:
365 void action (const CmtSystem::cmt_string_vector& words,
366 Use* use,
367 const cmt_string& file_name,
368 int line_number)
369 {
370 Symbol::action (words, CommandMacroPrepend, use);
371 }
372};
373
374class KwdMacroAppend : public Kwd
375{
376public:
377 void action (const CmtSystem::cmt_string_vector& words,
378 Use* use,
379 const cmt_string& file_name,
380 int line_number)
381 {
382 Symbol::action (words, CommandMacroAppend, use);
383 }
384};
385
386class KwdMacroRemove : public Kwd
387{
388public:
389 void action (const CmtSystem::cmt_string_vector& words,
390 Use* use,
391 const cmt_string& file_name,
392 int line_number)
393 {
394 Symbol::action (words, CommandMacroRemove, use);
395 }
396};
397
398class KwdMacroRemoveRegexp : public Kwd
399{
400public:
401 void action (const CmtSystem::cmt_string_vector& words,
402 Use* use,
403 const cmt_string& file_name,
404 int line_number)
405 {
406 Symbol::action (words, CommandMacroRemoveRegexp, use);
407 }
408};
409
410class KwdMacroRemoveAll : public Kwd
411{
412public:
413 void action (const CmtSystem::cmt_string_vector& words,
414 Use* use,
415 const cmt_string& file_name,
416 int line_number)
417 {
418 Symbol::action (words, CommandMacroRemoveAll, use);
419 }
420};
421
422class KwdMacroRemoveAllRegexp : public Kwd
423{
424public:
425 void action (const CmtSystem::cmt_string_vector& words,
426 Use* use,
427 const cmt_string& file_name,
428 int line_number)
429 {
430 Symbol::action (words, CommandMacroRemoveAllRegexp, use);
431 }
432};
433
434class KwdMakeFragment : 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 Fragment::action (words, use);
443 }
444};
445
446class KwdManager : public Kwd
447{
448public:
449 void action (const CmtSystem::cmt_string_vector& words,
450 Use* use,
451 const cmt_string& file_name,
452 int line_number)
453 {
454 use->manager_action (words);
455 }
456};
457
458class KwdPackage : public Kwd
459{
460public:
461 void action (const CmtSystem::cmt_string_vector& words,
462 Use* use,
463 const cmt_string& file_name,
464 int line_number)
465 {
466 /*
467 if (words.size () > 1)
468 {
469 if (use == &(Use::current()))
470 {
471 m_current_package = words[1];
472 build_prefix (m_current_package, m_current_prefix);
473
474 if ((use->get_package_name () != "") &&
475 (use->get_package_name () != m_current_package))
476 {
477 if (!m_quiet)
478 {
479 // cerr << "#CMT> package name mismatch in requirements of " <<
480 // use->get_package_name () << " " <<
481 // use->version << " line #" << line_number;
482 // cerr << " : " << m_current_package << " versus " <<
483 // use->get_package_name () << endl;
484 }
485 }
486
487 use->set (m_current_package,
488 m_current_version,
489 m_current_path,
490 "",
491 "");
492
493 use->change_path (m_current_path);
494 use->style = m_current_style;
495 }
496 }
497 */
498 }
499};
500
501class KwdPath : public Kwd
502{
503public:
504 void action (const CmtSystem::cmt_string_vector& words,
505 Use* use,
506 const cmt_string& file_name,
507 int line_number)
508 {
509 Symbol::action (words, CommandPath, use);
510 }
511};
512
513class KwdPathAppend : public Kwd
514{
515public:
516 void action (const CmtSystem::cmt_string_vector& words,
517 Use* use,
518 const cmt_string& file_name,
519 int line_number)
520 {
521 Symbol::action (words, CommandPathAppend, use);
522 }
523};
524
525class KwdPathPrepend : public Kwd
526{
527public:
528 void action (const CmtSystem::cmt_string_vector& words,
529 Use* use,
530 const cmt_string& file_name,
531 int line_number)
532 {
533 Symbol::action (words, CommandPathPrepend, use);
534 }
535};
536
537class KwdPathRemove : public Kwd
538{
539public:
540 void action (const CmtSystem::cmt_string_vector& words,
541 Use* use,
542 const cmt_string& file_name,
543 int line_number)
544 {
545 Symbol::action (words, CommandPathRemove, use);
546 }
547};
548
549class KwdPathRemoveRegexp : public Kwd
550{
551public:
552 void action (const CmtSystem::cmt_string_vector& words,
553 Use* use,
554 const cmt_string& file_name,
555 int line_number)
556 {
557 Symbol::action (words, CommandPathRemoveRegexp, use);
558 }
559};
560
561class KwdPattern : public Kwd
562{
563public:
564 void action (const CmtSystem::cmt_string_vector& words,
565 Use* use,
566 const cmt_string& file_name,
567 int line_number)
568 {
569 Pattern::action (words, use);
570 }
571};
572
573class KwdPrivate : public Kwd
574{
575public:
576 void action (const CmtSystem::cmt_string_vector& words,
577 Use* use,
578 const cmt_string& file_name,
579 int line_number)
580 {
581 if (use != &(Use::current ()))
582 {
583 use->push_scope_section (ScopePrivate);
584 }
585 }
586};
587
588class KwdProject : public Kwd
589{
590public:
591 void action (const CmtSystem::cmt_string_vector& words,
592 Use* use,
593 const cmt_string& file_name,
594 int line_number)
595 {
596 }
597
598 void action (const CmtSystem::cmt_string_vector& words,
599 Project* project,
600 const cmt_string& file_name,
601 int line_number)
602 {
603 }
604};
605
606class KwdPublic : public Kwd
607{
608public:
609 void action (const CmtSystem::cmt_string_vector& words,
610 Use* use,
611 const cmt_string& file_name,
612 int line_number)
613 {
614 if (use != &(Use::current ()))
615 {
616 use->push_scope_section (ScopePublic);
617 }
618 }
619};
620
621class KwdSet : public Kwd
622{
623public:
624 void action (const CmtSystem::cmt_string_vector& words,
625 Use* use,
626 const cmt_string& file_name,
627 int line_number)
628 {
629 Symbol::action (words, CommandSet, use);
630 }
631};
632
633class KwdSetAppend : public Kwd
634{
635public:
636 void action (const CmtSystem::cmt_string_vector& words,
637 Use* use,
638 const cmt_string& file_name,
639 int line_number)
640 {
641 Symbol::action (words, CommandSetAppend, use);
642 }
643};
644
645class KwdSetPrepend : public Kwd
646{
647public:
648 void action (const CmtSystem::cmt_string_vector& words,
649 Use* use,
650 const cmt_string& file_name,
651 int line_number)
652 {
653 Symbol::action (words, CommandSetPrepend, use);
654 }
655};
656
657class KwdSetRemove : public Kwd
658{
659public:
660 void action (const CmtSystem::cmt_string_vector& words,
661 Use* use,
662 const cmt_string& file_name,
663 int line_number)
664 {
665 Symbol::action (words, CommandSetRemove, use);
666 }
667};
668
669class KwdSetRemoveRegexp : public Kwd
670{
671public:
672 void action (const CmtSystem::cmt_string_vector& words,
673 Use* use,
674 const cmt_string& file_name,
675 int line_number)
676 {
677 Symbol::action (words, CommandSetRemoveRegexp, use);
678 }
679};
680
681class KwdSetupScript : public Kwd
682{
683public:
684 void action (const CmtSystem::cmt_string_vector& words,
685 Use* use,
686 const cmt_string& file_name,
687 int line_number)
688 {
689 Script::action (words, SetupScript, use);
690 Symbol::action (words, CommandSetupScript, use);
691 }
692};
693
694class KwdSetupStrategy : public Kwd
695{
696public:
697 bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
698 {
699 bool result = true;
700
701 value = w;
702
703 if (w == "config")
704 {
705 strategy = "SetupConfig";
706 }
707 else if (w == "no_config")
708 {
709 strategy = "SetupConfig";
710 }
711 else if (w == "root")
712 {
713 strategy = "SetupRoot";
714 }
715 else if (w == "no_root")
716 {
717 strategy = "SetupRoot";
718 }
719 else if (w == "cleanup")
720 {
721 strategy = "SetupCleanup";
722 }
723 else if (w == "no_cleanup")
724 {
725 strategy = "SetupCleanup";
726 }
727 else
728 {
729 result = false;
730 }
731
732 return (result);
733 }
734
735 void action (const CmtSystem::cmt_string_vector& words,
736 Use* use,
737 const cmt_string& file_name,
738 int line_number)
739 {
740 cmt_string cmtpath;
741 cmt_string offset;
742
743 use->get_cmtpath_and_offset (cmtpath, offset);
744
745 Project* p = Project::find_by_cmtpath (cmtpath);
746
747 for (int i = 1; i < words.size (); i++)
748 {
749 const cmt_string& w = words[i];
750
751 cmt_string strategy;
752 cmt_string value;
753
754 bool in_error = false;
755
756 if (decode (w, strategy, value))
757 {
758 if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
759 }
760 else
761 {
762 in_error = true;
763
764 CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
765 }
766 }
767 }
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 for (int i = 1; i < words.size (); i++)
775 {
776 const cmt_string& w = words[i];
777
778 cmt_string strategy;
779 cmt_string value;
780
781 bool in_error = false;
782
783 if (decode (w, strategy, value))
784 {
785 if (project != 0) project->set_strategy (strategy, value, "");
786 }
787 else
788 {
789 in_error = true;
790
791 CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
792 }
793 }
794 }
795};
796
797class KwdTag : public Kwd
798{
799public:
800 void action (const CmtSystem::cmt_string_vector& words,
801 Use* use,
802 const cmt_string& file_name,
803 int line_number)
804 {
805 Tag::action (words, use);
806 }
807};
808
809class KwdTagExclude : public Kwd
810{
811public:
812 void action (const CmtSystem::cmt_string_vector& words,
813 Use* use,
814 const cmt_string& file_name,
815 int line_number)
816 {
817 Tag::action_exclude (words, use);
818 }
819};
820
821class KwdUse : public Kwd
822{
823public:
824 void action (const CmtSystem::cmt_string_vector& words,
825 Use* use,
826 const cmt_string& file_name,
827 int line_number)
828 {
829 Use::action (words, use);
830 }
831
832 void action (const CmtSystem::cmt_string_vector& words,
833 Project* project,
834 const cmt_string& file_name,
835 int line_number)
836 {
837 project->use_action (words[1], words[2]);
838 }
839};
840
841class KwdVersionStrategy : public Kwd
842{
843public:
844 void action (const CmtSystem::cmt_string_vector& words,
845 Use* use,
846 const cmt_string& file_name,
847 int line_number)
848 {
849 cerr << "# Package " << use->get_package_name () <<
850 " sets obsolescent version strategy" << endl;
851 }
852};
853
854class KwdVersion : public Kwd
855{
856public:
857 void action (const CmtSystem::cmt_string_vector& words,
858 Use* use,
859 const cmt_string& file_name,
860 int line_number)
861 {
862 }
863};
864
865class KwdDefault : 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 Unknown keyword : just ignore the line
875 */
876 if (!Cmt::get_quiet ())
877 {
878 cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
879 << " " << use->version << " line #" << line_number;
880 cerr << " [" << words[0] << "...]" << endl;
881 }
882
883 CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
884 }
885};
886
887SyntaxParser& SyntaxParser::instance ()
888{
889 static SyntaxParser p;
890
891 return (p);
892}
893
894/**
895 * Parse the input file, rejecting comments and
896 * rebuilding complete lines (from sections separated by
897 * \ characters.
898 *
899 * Each reformatted line is parsed by filter_line
900 */
901void SyntaxParser::parse_requirements (const cmt_string& file_name, Use* use)
902{
903 SyntaxParser& me = instance ();
904
905 if (use != 0)
906 {
907 cmt_string buffer;
908
909 use->fill_standard_macros (buffer);
910
911 AccessMode saved_current_access = Cmt::get_current_access ();
912 Cmt::set_current_access (UserMode);
913 me.do_parse_text (buffer, "", package_context, use, 0);
914 Cmt::set_current_access (saved_current_access);
915 }
916
917 me.do_parse_requirements (file_name, use);
918
919 if (use != 0)
920 {
921 use->close_scope_sections ();
922 }
923}
924
925/**
926 */
927void SyntaxParser::parse_project_file_text (const cmt_string& text,
928 const cmt_string& file_name,
929 Project* project)
930{
931 SyntaxParser& me = instance ();
932 me.do_parse_text (text, file_name, project_context, 0, project);
933}
934
935/**
936 * Parse a text, rejecting comments and
937 * rebuilding complete lines (from sections separated by
938 * \ characters.
939 *
940 * Each reformatted line is parsed by filter_line
941 */
942void SyntaxParser::parse_requirements_text (const cmt_string& text,
943 const cmt_string& file_name,
944 Use* use)
945{
946 SyntaxParser& me = instance ();
947
948 /**
949 *
950 * We have to preserve m_current_access since it reflects whether
951 * the current cmt action is run in the context of the current package.
952 * (the opposite is when the cmt command specifies the current package
953 * in its arguments -use=... therefore the pwd is NOT the directory
954 * of the current package)
955 *
956 * m_current_access is Developer when pwd = current
957 * User when pwd != current
958 *
959 * Therefore, as soon as we reach a used package, this must be switched to User
960 *
961 * On the other hand, Cmt::scope reflects the status of the public/private
962 * statements. By default, we are in public context when entering a new requirements
963 * file.
964 *
965 */
966
967 AccessMode saved_current_access;
968
969 saved_current_access = Cmt::get_current_access ();
970
971 if (use == 0) use = &(Use::current ());
972
973 if (use != &(Use::current ()))
974 {
975 if (Cmt::get_debug ())
976 {
977 cout << "parse_requirements_text> set UserMode" << endl;
978 }
979
980 Cmt::set_current_access (UserMode);
981 }
982 else
983 {
984 if (Cmt::get_debug ())
985 {
986 cout << "parse_requirements_text> set DeveloperMode" << endl;
987 }
988
989 Cmt::set_current_access (DeveloperMode);
990 }
991
992 me.do_parse_text (text, file_name, package_context, use, 0);
993
994 Cmt::set_current_access (saved_current_access);
995}
996
997/**
998 * Apply the basic parser to one single line :
999 *
1000 * o Append to global text if previous back_slash
1001 * o Split into words
1002 * o Apply the generic Select operator
1003 */
1004void SyntaxParser::parse_requirements_line (const cmt_string& line,
1005 Use* use,
1006 const cmt_string& file_name,
1007 int line_number)
1008{
1009 SyntaxParser& me = instance ();
1010 me.do_parse_line (line, file_name, line_number, package_context, use, 0);
1011}
1012
1013SyntaxParser::SyntaxParser ()
1014{
1015 m_keywords.add ("action", new KwdAction ());
1016 m_keywords.add ("alias", new KwdAlias ());
1017 m_keywords.add ("application", new KwdApplication ());
1018 m_keywords.add ("apply_pattern", new KwdApplyPattern ());
1019 m_keywords.add ("apply_tag", new KwdApplyTag ());
1020 m_keywords.add ("author", new KwdAuthor ());
1021 m_keywords.add ("branches", new KwdBranches ());
1022 m_keywords.add ("build_strategy", new KwdBuildStrategy ());
1023 m_keywords.add ("cleanup_script", new KwdCleanupScript ());
1024 m_keywords.add ("cmtpath_pattern", new KwdCmtPathPattern ());
1025 m_keywords.add ("document", new KwdDocument ());
1026 m_keywords.add ("end_private", new KwdEndPrivate ());
1027 m_keywords.add ("end_public", new KwdEndPublic ());
1028 m_keywords.add ("ignore_pattern", new KwdIgnorePattern ());
1029 m_keywords.add ("include_dirs", new KwdIncludeDirs ());
1030 m_keywords.add ("include_path", new KwdIncludePath ());
1031 m_keywords.add ("language", new KwdLanguage ());
1032 m_keywords.add ("library", new KwdLibrary ());
1033 m_keywords.add ("macro", new KwdMacro ());
1034 m_keywords.add ("macro+", new KwdMacroAppend ());
1035 m_keywords.add ("macro_prepend", new KwdMacroPrepend ());
1036 m_keywords.add ("macro_append", new KwdMacroAppend ());
1037 m_keywords.add ("macro_remove", new KwdMacroRemove ());
1038 m_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ());
1039 m_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ());
1040 m_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ());
1041 m_keywords.add ("make_fragment", new KwdMakeFragment ());
1042 m_keywords.add ("manager", new KwdManager ());
1043 m_keywords.add ("package", new KwdPackage ());
1044 m_keywords.add ("path", new KwdPath ());
1045 m_keywords.add ("path_append", new KwdPathAppend ());
1046 m_keywords.add ("path_prepend", new KwdPathPrepend ());
1047 m_keywords.add ("path_remove", new KwdPathRemove ());
1048 m_keywords.add ("path_remove_regexp", new KwdPathRemoveRegexp ());
1049 m_keywords.add ("pattern", new KwdPattern ());
1050 m_keywords.add ("public", new KwdPublic ());
1051 m_keywords.add ("private", new KwdPrivate ());
1052 m_keywords.add ("project", new KwdProject ());
1053 m_keywords.add ("set", new KwdSet ());
1054 m_keywords.add ("set_append", new KwdSetAppend ());
1055 m_keywords.add ("set_prepend", new KwdSetPrepend ());
1056 m_keywords.add ("set_remove", new KwdSetRemove ());
1057 m_keywords.add ("set_remove_regexp", new KwdSetRemoveRegexp ());
1058 m_keywords.add ("setup_script", new KwdSetupScript ());
1059 m_keywords.add ("setup_strategy", new KwdSetupStrategy ());
1060 m_keywords.add ("tag", new KwdTag ());
1061 m_keywords.add ("tag_exclude", new KwdTagExclude ());
1062 m_keywords.add ("use", new KwdUse ());
1063 m_keywords.add ("version_strategy", new KwdVersionStrategy ());
1064 m_keywords.add ("version", new KwdVersion ());
1065
1066 m_project_keywords.add ("build_strategy", new KwdBuildStrategy ());
1067 m_project_keywords.add ("project", new KwdProject ());
1068 m_project_keywords.add ("setup_strategy", new KwdSetupStrategy ());
1069 m_project_keywords.add ("use", new KwdUse ());
1070}
1071
1072void SyntaxParser::do_parse_requirements (const cmt_string& file_name, Use* use)
1073{
1074 cmt_string actual_file_name = file_name;
1075 cmt_string text;
1076
1077 CmtError::clear ();
1078
1079 if (!CmtSystem::test_file (actual_file_name))
1080 {
1081 actual_file_name = "..";
1082 actual_file_name += CmtSystem::file_separator ();
1083 actual_file_name += "cmt";
1084 actual_file_name += CmtSystem::file_separator ();
1085 actual_file_name += file_name;
1086
1087 if (!CmtSystem::test_file (actual_file_name))
1088 {
1089 actual_file_name = "..";
1090 actual_file_name += CmtSystem::file_separator ();
1091 actual_file_name += "mgr";
1092 actual_file_name += CmtSystem::file_separator ();
1093 actual_file_name += file_name;
1094
1095 if (!CmtSystem::test_file (actual_file_name))
1096 {
1097 return;
1098 }
1099 }
1100 }
1101
1102 text.read (actual_file_name);
1103
1104 SyntaxParser::parse_requirements_text (text, actual_file_name, use);
1105}
1106
1107/**
1108 * Parse a text, rejecting comments and
1109 * rebuilding complete lines (from sections separated by
1110 * \ characters.
1111 *
1112 * Each reformatted line is parsed by filter_line
1113 */
1114void SyntaxParser::do_parse_text (const cmt_string& text,
1115 const cmt_string& file_name,
1116 ContextType context,
1117 Use* use,
1118 Project* project)
1119{
1120 cmt_string line;
1121 int pos;
1122 int max_pos;
1123 int line_number = 1;
1124
1125 if (context == package_context)
1126 {
1127 if (use == 0) use = &(Use::current ());
1128 }
1129
1130 m_filtered_text.erase (0);
1131
1132 pos = 0;
1133 max_pos = text.size ();
1134
1135 for (pos = 0; pos < max_pos;)
1136 {
1137 int cr = text.find (pos, "\r\n");
1138 int nl = text.find (pos, '\n');
1139 int first = nl;
1140 int length = 1;
1141
1142 if (cr != cmt_string::npos)
1143 {
1144 if (nl == cmt_string::npos)
1145 {
1146 first = cr;
1147 length = 2;
1148 }
1149 else
1150 {
1151 first = (nl < cr) ? nl : cr;
1152 length = (nl < cr) ? 1 : 2;
1153 }
1154 }
1155
1156 if (first == cmt_string::npos)
1157 {
1158 text.substr (pos, line);
1159 pos = max_pos;
1160 }
1161 else if (first > pos)
1162 {
1163 text.substr (pos, first - pos, line);
1164 pos = first + length;
1165 }
1166 else
1167 {
1168 line.erase (0);
1169 pos += length;
1170 }
1171
1172 do_parse_line (line, file_name, line_number, context, use, project);
1173
1174 if ((Cmt::get_action () == action_check_configuration) && CmtError::has_pending_error ())
1175 {
1176 //break;
1177 }
1178
1179 line_number++;
1180 }
1181}
1182
1183void SyntaxParser::do_parse_line (const cmt_string& line,
1184 const cmt_string& file_name,
1185 int line_number,
1186 ContextType context,
1187 Use* use,
1188 Project* project)
1189{
1190 int length;
1191 int nl;
1192 int back_slash;
1193 cmt_string temp_line = line;
1194
1195 if (temp_line.size () == 0) return;
1196 if (temp_line[0] == '#') return;
1197
1198 nl = temp_line.find_last_of ('\n');
1199 if (nl != cmt_string::npos) temp_line.erase (nl);
1200
1201 length = temp_line.size ();
1202 if (length == 0) return;
1203
1204 //
1205 // We scan the line for handling backslashes.
1206 //
1207 // o Really terminating backslashes (ie those only followed by spaces/tabs
1208 // mean continued line
1209 //
1210 //
1211
1212 bool finished = true;
1213
1214 length = temp_line.size ();
1215
1216 back_slash = temp_line.find_last_of ('\\');
1217
1218 if (back_slash != cmt_string::npos)
1219 {
1220 //
1221 // This is the last backslash
1222 // check if there are only space chars after it
1223 //
1224
1225 bool at_end = true;
1226
1227 for (int i = (back_slash + 1); i < length; i++)
1228 {
1229 char c = temp_line[i];
1230 if ((c != ' ') && (c != '\t'))
1231 {
1232 at_end = false;
1233 break;
1234 }
1235 }
1236
1237 if (at_end)
1238 {
1239 temp_line.erase (back_slash);
1240 finished = false;
1241 }
1242 else
1243 {
1244 // This was not a trailing backslash.
1245 finished = true;
1246 }
1247 }
1248
1249 m_filtered_text += temp_line;
1250
1251 if (!finished)
1252 {
1253 // We still need to accumulate forthcoming lines
1254 // before parsing the resulting text.
1255 return;
1256 }
1257
1258 /*
1259 Here a full line (possibly accumulating several lines
1260 ended by backslashes) is parsed :
1261
1262 o Special characters are filtered now :
1263
1264 <cmt:tab/> \t
1265 <cmt:cr/> \r
1266 <cmt:lf/> \n
1267
1268 o Split into words (a word is a string not containing
1269 spaces or enclosed in quotes)
1270
1271 o Parse the word array (function Select)
1272
1273 */
1274
1275 m_filtered_text.replace_all ("<cmt:tab/>", "\t");
1276 m_filtered_text.replace_all ("<cmt:cr/>", "\r");
1277 m_filtered_text.replace_all ("<cmt:lf/>", "\n");
1278
1279 if (Cmt::get_debug ())
1280 {
1281 cout << "parse_requirements_line [" << m_filtered_text << "]" << endl;
1282 }
1283
1284 static CmtSystem::cmt_string_vector words;
1285
1286 CmtSystem::split (m_filtered_text, " \t", words);
1287
1288 if (words.size () != 0)
1289 {
1290 switch (context)
1291 {
1292 case project_context:
1293 do_parse_words (words, file_name, line_number, project);
1294 break;
1295 case package_context:
1296 do_parse_words (words, file_name, line_number, use);
1297 break;
1298 }
1299 }
1300
1301 m_filtered_text.erase (0);
1302}
1303
1304void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
1305 const cmt_string& file_name,
1306 int line_number,
1307 Use* use)
1308{
1309 CmtError::clear ();
1310
1311 if (words.size () == 0) return;
1312
1313 const cmt_string& command = words[0];
1314
1315 if (command.size () == 0) return;
1316
1317 //
1318 // First analyze the syntax
1319 //
1320
1321 Kwd* keyword = m_keywords.find (command);
1322 if (keyword == 0)
1323 {
1324 /*
1325
1326 When the first word of the line is not a keyword, it may be an
1327 implicit pattern application.
1328
1329 */
1330
1331 Pattern* p = Pattern::find (command);
1332 if (p == 0)
1333 {
1334 CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
1335 }
1336 else
1337 {
1338 keyword = m_keywords.find ("apply_pattern");
1339 }
1340 }
1341
1342 if (CmtError::has_pending_error ())
1343 {
1344 if (!Cmt::get_quiet ())
1345 {
1346 cerr << "#CMT> bad syntax in requirements of " << use->get_package_name ()
1347 << " " << use->version
1348 << " " << use->specified_path
1349 << " line #" << line_number;
1350 cerr << " [" << command << " ...]" << endl;
1351 }
1352
1353 return;
1354 }
1355
1356 //
1357 // Then interpret the action
1358 //
1359
1360 keyword->action (words, use, file_name, line_number);
1361}
1362
1363void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words,
1364 const cmt_string& file_name,
1365 int line_number,
1366 Project* project)
1367{
1368 CmtError::clear ();
1369
1370 if (words.size () == 0) return;
1371
1372 const cmt_string& command = words[0];
1373
1374 if (command.size () == 0) return;
1375
1376 //
1377 // First analyze the syntax
1378 //
1379
1380 Kwd* keyword = m_project_keywords.find (command);
1381 if (keyword == 0)
1382 {
1383 CmtError::set (CmtError::syntax_error, "ParseRequirements> ");
1384 }
1385
1386 if (CmtError::has_pending_error ())
1387 {
1388 if (!Cmt::get_quiet ())
1389 {
1390 cerr << "#CMT> bad syntax in project file of " << project->get_name ()
1391 << " line #" << line_number;
1392 cerr << " [" << command << " ...]" << endl;
1393 }
1394
1395 return;
1396 }
1397
1398 //
1399 // Then interpret the action
1400 //
1401
1402 keyword->action (words, project, file_name, line_number);
1403}
1404
1405
1406
1407
Note: See TracBrowser for help on using the repository browser.