source: CMT/v1r20b1/source/cmt_generators.cxx@ 327

Last change on this file since 327 was 197, checked in by garonne, 19 years ago

add the STRUCTURED_OUTPUT support on linux +mac

  • Property svn:eol-style set to native
File size: 76.3 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_generators.h"
8#include "cmt_awk.h"
9#include "cmt_use.h"
10#include "cmt_symbol.h"
11#include "cmt_log.h"
12
13//--------------------------------------------------
14AnyDocumentGenerator::AnyDocumentGenerator ()
15{
16 m_TITLE.set ("TITLE");
17 m_STRUCTURED_OUTPUT.set ("STRUCTURED_OUTPUT");
18
19 make_header_fragment.set ("make_header");
20 cleanup_header_fragment.set ("cleanup_header");
21 cleanup_fragment.set ("cleanup");
22 dependencies_fragment.set ("dependencies");
23 dependencies_and_triggers_fragment.set ("dependencies_and_triggers");
24}
25
26void AnyDocumentGenerator::reset ()
27{
28 CmtGenerator::reset ();
29 m_TITLE = "";
30
31 make_header_fragment.reset ();
32 cleanup_header_fragment.reset ();
33 cleanup_fragment.reset ();
34 dependencies_fragment.reset ();
35 dependencies_and_triggers_fragment.reset ();
36}
37
38//--------------------------------------------------
39LibraryGenerator::LibraryGenerator ()
40{
41 library_header_fragment.set ("library_header");
42 application_header_fragment.set ("application_header");
43 java_header_fragment.set ("java_header");
44 jar_header_fragment.set ("jar_header");
45 protos_header_fragment.set ("protos_header");
46 library_fragment.set ("library");
47 library_no_share_fragment.set ("library_no_share");
48 application_fragment.set ("application");
49 jar_fragment.set ("jar");
50 java_fragment.set ("java");
51 java_copy_fragment.set ("java_copy");
52 cleanup_library_fragment.set ("cleanup_library");
53 cleanup_application_fragment.set ("cleanup_application");
54 cleanup_java_fragment.set ("cleanup_java");
55 cleanup_objects_fragment.set ("cleanup_objects");
56 buildproto_fragment.set ("buildproto");
57 check_application_fragment.set ("check_application");
58 check_java_fragment.set ("check_java");
59}
60
61//--------------------------------------------------
62void LibraryGenerator::reset ()
63{
64 AnyDocumentGenerator::reset ();
65 library_header_fragment.reset ();
66 application_header_fragment.reset ();
67 java_header_fragment.reset ();
68 jar_header_fragment.reset ();
69 protos_header_fragment.reset ();
70 library_fragment.reset ();
71 library_no_share_fragment.reset ();
72 jar_fragment.reset ();
73 application_fragment.reset ();
74 java_fragment.reset ();
75 java_copy_fragment.reset ();
76 cleanup_library_fragment.reset ();
77 cleanup_application_fragment.reset ();
78 cleanup_java_fragment.reset ();
79 cleanup_objects_fragment.reset ();
80 buildproto_fragment.reset ();
81 check_application_fragment.reset ();
82 check_java_fragment.reset ();
83}
84
85//--------------------------------------------------
86bool LibraryGenerator::analyze_file (const Constituent& constituent,
87 const cmt_string& file)
88{
89 static cmt_string suffix;
90 static cmt_string name;
91 static cmt_string obj;
92
93 bool file_not_found = false;
94 bool can_build = true;
95
96 obj = file;
97
98 if (Cmt::get_debug ())
99 {
100 cout << "CmtGenerator::analyze_file> constituent=" <<
101 constituent.name <<
102 " file=" << file << endl;
103 }
104
105 if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file))
106 {
107 file_not_found = true;
108 cerr << "#CMT> Warning: Source file " << file << " not found" << endl;
109 }
110
111 CmtSystem::get_suffix (file, suffix);
112 CmtSystem::basename (file, suffix, name);
113
114 Language& language = Language::find_with_suffix (suffix);
115
116 if (m_LINKMACRO == "")
117 {
118 m_LINKMACRO = language.linker;
119 }
120
121 if (language == "java")
122 {
123 static Packager packager;
124
125 obj = "$(javabin)";
126 obj += m_CONSTITUENT;
127 obj += CmtSystem::file_separator ();
128
129 cmt_regexp exp ("^package[ \t][ \t]*[a-zA-Z0-9_.][a-zA-Z0-9_.][ \t]*;");
130
131 packager.run (file, exp);
132 if (packager.package_name () != "")
133 {
134 obj += packager.package_name ();
135 obj += CmtSystem::file_separator ();
136 }
137
138 obj += name;
139 obj += ".class";
140 }
141 else if (language != Language::null ())
142 {
143 obj = "$(bin)";
144
145 if (CmtSystem::getenv("STRUCTURED_OUTPUT")!="" || Cmt::build_nmake ())
146 {
147 obj += m_CONSTITUENT;
148 obj += CmtSystem::file_separator ();
149 }
150
151 obj += name;
152 obj += language.output_suffix;
153 obj += constituent.suffix;
154 if (Cmt::build_nmake ()) obj += ".obj";
155 else obj += ".o";
156
157 for (int i = 0; i < language.extra_output_suffixes.size (); i++)
158 {
159 cmt_string& extra_suffix = language.extra_output_suffixes[i];
160
161 obj += " $(bin)";
162 obj += name;
163 obj += extra_suffix;
164 obj += language.output_suffix;
165 obj += constituent.suffix;
166 if (Cmt::build_nmake ()) obj += ".obj";
167 else obj += ".o";
168 }
169 }
170 else
171 {
172 //cout << "#CMT> analyze_file file=" << file << " no language" << endl;
173
174 if (m_LINKMACRO == "java")
175 {
176 obj = "$(javabin)";
177 obj += m_CONSTITUENT;
178 obj += CmtSystem::file_separator ();
179 obj += file;
180
181 obj.replace ("../src/", "");
182 obj.replace ("..\\src\\", "");
183 }
184 else if (file_not_found)
185 {
186 can_build = false;
187 obj = "";
188 cerr << "#CMT> Warning: Source file " << name << " cannot be rebuilt" << endl;
189 }
190 else
191 {
192 obj = "";
193 }
194 }
195
196 if (Cmt::get_debug ())
197 {
198 cout << "CmtGenerator::analyze_file> constituent=" <<
199 constituent.name <<
200 " obj=" << obj << endl;
201 }
202
203 if (can_build)
204 {
205 SourceFile& source = m_source_files.add ();
206 source.set (file, language, obj);
207 return (true);
208 }
209 else
210 {
211 return (false);
212 }
213}
214
215//--------------------------------------------------
216void LibraryGenerator::java_file_action (SourceFile& file, const Constituent& constituent)
217{
218 static cmt_string suffix;
219
220 m_FULLNAME = file.name ();
221 m_OUTPUTNAME = file.output ();
222
223 CmtSystem::get_dot_suffix (m_FULLNAME, suffix);
224
225 CmtSystem::basename (m_FULLNAME, suffix, m_NAME.value);
226 CmtSystem::basename (m_FULLNAME, m_FILENAME.value);
227
228 if (CmtSystem::test_file (m_FULLNAME))
229 {
230 java_fragment.copy (m_output_file, constituent.variables, 5,
231 &m_NAME,
232 &m_FULLNAME,
233 &m_OUTPUTNAME,
234 &m_CONSTITUENT,
235 &m_CONSTITUENTSUFFIX);
236 }
237 else
238 {
239 cerr << "#CMT> Warning: file " << m_FULLNAME << " not found" << endl;
240 }
241}
242
243//--------------------------------------------------
244void LibraryGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent)
245{
246 static cmt_string suffix;
247
248 CmtSystem::dirname (file, m_FILEPATH.value);
249 if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
250
251 filter_path (m_FILEPATH.value);
252
253 CmtSystem::basename (file, m_FILENAME.value);
254 CmtSystem::get_dot_suffix (m_FILENAME, suffix);
255
256 CmtSystem::basename (m_FILENAME, suffix, m_NAME.value);
257
258 buildproto_fragment.copy (m_output_file, constituent.variables, 3,
259 &m_NAME,
260 &m_FILEPATH,
261 &m_FILENAME);
262}
263
264//--------------------------------------------------
265void LibraryGenerator::prepare_proto_file (const cmt_string& file)
266{
267 static cmt_string name;
268 static cmt_string pp;
269
270 CmtSystem::name (file, name);
271
272 if (CmtSystem::test_file (file))
273 {
274 pp = incdir;
275 pp += name;
276 pp += ".pp";
277
278 if (!CmtSystem::test_file (pp))
279 {
280 //Generator::build_prototype (file);
281 }
282 }
283
284 protos += " ";
285 protos += inc;
286 protos += name;
287 protos += ".ph";
288
289 protonames += " ";
290 protonames += name;
291 protonames += ".ph";
292
293 m_PROTOSTAMPS += " ";
294 m_PROTOSTAMPS += inc;
295 m_PROTOSTAMPS += name;
296 m_PROTOSTAMPS += ".pp";
297}
298
299//--------------------------------------------------
300void LibraryGenerator::module_file_action (SourceFile& file, const Constituent& constituent)
301{
302 cmt_string name = file.name ();
303 Language& language = file.language ();
304
305 static cmt_string suffix;
306 static cmt_string prefix;
307 static cmt_string preproc;
308
309 m_FULLNAME = name;
310
311 CmtSystem::get_dot_suffix (name, suffix);
312
313 CmtSystem::basename (name, suffix, m_NAME.value);
314
315 CmtSystem::dirname (name, prefix);
316 CmtSystem::basename (name, m_FILENAME.value);
317
318 FragmentHandle* fragment;
319
320 if (language != Language::null ())
321 {
322 preproc = language.preprocessor_command;
323 fragment = (is_library) ? &(language.library) : &(language.application);
324 }
325 else
326 {
327 //
328 // What happens when the language is not known???
329 //
330 //
331 preproc = "-I";
332 fragment = 0;
333 }
334
335 if ((prefix == "../src") || (prefix == "..\\src"))
336 {
337 m_ADDINCLUDE = "";
338 }
339 else if (prefix != "")
340 {
341 m_ADDINCLUDE = preproc;
342 m_ADDINCLUDE += prefix;
343 }
344
345 m_FILEPATH = prefix;
346 if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
347 filter_path (m_FILEPATH.value);
348
349 m_LINE = m_FULLNAME.value;
350 m_LINE += " ";
351
352 filter_path (m_FULLNAME.value);
353 filter_path (m_LINE.value);
354
355 CmtSystem::get_suffix (name, m_FILESUFFIX.value);
356
357 if (fragment != 0)
358 {
359 fragment->copy (m_output_file, constituent.variables, 10,
360 &m_CONSTITUENT,
361 &m_CONSTITUENTSUFFIX,
362 &m_FILENAME,
363 &m_NAME,
364 &m_LINE,
365 &m_ADDINCLUDE,
366 &m_FULLNAME,
367 &m_FILEPATH,
368 &m_FILESUFFIX,
369 &m_PACKAGE);
370 }
371 else if (file.output () != "")
372 {
373 m_OUTPUTNAME = file.output ();
374 CmtSystem::dirname (m_OUTPUTNAME.value, m_FILEPATH.value);
375
376 java_copy_fragment.copy (m_output_file, constituent.variables, 11,
377 &m_CONSTITUENT,
378 &m_CONSTITUENTSUFFIX,
379 &m_FILENAME,
380 &m_NAME,
381 &m_LINE,
382 &m_ADDINCLUDE,
383 &m_FULLNAME,
384 &m_FILEPATH,
385 &m_FILESUFFIX,
386 &m_PACKAGE,
387 &m_OUTPUTNAME);
388 }
389
390 if (m_PACKOS9)
391 {
392 os9sources += m_LINE;
393 os9sources += " ";
394 }
395}
396
397//--------------------------------------------------
398void LibraryGenerator::build (const cmt_string& package,
399 const Constituent& constituent)
400{
401 static cmt_string lib;
402 static cmt_string allsources;
403 static cmt_string file;
404 static cmt_string full_name;
405 static cmt_string compressed_name;
406 static cmt_string suffix;
407 int i;
408 bool need_prototypes;
409
410 reset ();
411
412 if (!prepare_output (package, constituent)) return;
413
414 switch (constituent.type)
415 {
416 case Application:
417 is_library = false;
418 is_application = true;
419 m_TITLE = "Application";
420 break;
421 case Library:
422 is_library = true;
423 is_application = false;
424 m_TITLE = "Library";
425 break;
426 }
427
428 m_source_files.clear ();
429
430 need_prototypes = constituent.need_prototypes;
431
432 cout << m_TITLE << " " << m_CONSTITUENT << endl;
433
434 lib = "$(";
435 lib += m_CONSTITUENT;
436 lib += "lib)";
437
438 //
439 // Prepare the include paths
440 //
441
442 const CmtSystem::cmt_string_vector& includes = constituent.includes;
443
444 for (i = 0; i < includes.size (); i++)
445 {
446 const cmt_string& subdir = includes[i];
447
448 m_PACKINCLUDES += " -I";
449 m_PACKINCLUDES += subdir;
450 }
451
452 //
453 // Scan the sources.
454 //
455
456 const CmtSystem::cmt_string_vector& sources = constituent.modules;
457 const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
458 const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
459
460 m_LINE = "";
461
462 for (i = 0; i < sources.size (); i++)
463 {
464 file = sources[i];
465
466 set_full_name (full_name, file);
467 if (full_name == "") continue;
468
469 CmtSystem::compress_path (full_name, compressed_name);
470 full_name = compressed_name;
471
472 static CmtSystem::cmt_string_vector files;
473
474 int count = get_all_files (full_name, excludes, selects, files);
475
476 filter_path (full_name);
477
478 for (int j = 0; j < files.size (); j++)
479 {
480 const cmt_string& name = files[j];
481
482 if (name != "")
483 {
484 if (!analyze_file (constituent, name))
485 {
486 count = 0;
487 break;
488 }
489 }
490 }
491
492 if (count > 0)
493 {
494 m_LINE += full_name;
495 m_LINE += " ";
496 }
497 }
498
499 fill_outputs ();
500
501 prepare_use_context ();
502
503 m_DATE = CmtSystem::now ();
504 m_USER = CmtSystem::user ();
505 m_PACKAGE = package;
506
507 if (constituent.has_target_tag)
508 {
509 m_HASTARGETTAG = "has_target_tag";
510 }
511 else
512 {
513 m_HASTARGETTAG = "has_no_target_tag";
514 }
515
516 m_STRUCTURED_OUTPUT = "STRUCTURED_OUTPUT";
517
518 make_header_fragment.copy (m_output_file, constituent.variables, 8,
519 &m_TITLE,
520 &m_CONSTITUENT,
521 &m_CONSTITUENTSUFFIX,
522 &m_USER,
523 &m_DATE,
524 &m_PACKAGE,
525 &m_HASTARGETTAG,
526 &m_STRUCTURED_OUTPUT
527 );
528
529 if (need_prototypes)
530 {
531 need_prototypes = false;
532
533 for (i = 0; i < m_source_files.size (); i++)
534 {
535 const SourceFile& file = m_source_files[i];
536 Language& language = file.language ();
537 if (language.prototypes)
538 {
539 need_prototypes = true;
540 break;
541 }
542 }
543 }
544
545 //-------------------------------------------
546 //
547 // Specific targets (application, library or java)
548 // Prepare in case prototype files are needed
549 //
550 //-------------------------------------------
551
552 m_PROTOTARGET = "";
553
554 //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
555 if (need_prototypes)
556 {
557 m_PROTOTARGET = m_CONSTITUENT;
558 m_PROTOTARGET += "PROTOS";
559 }
560
561 if (m_LINKMACRO == "java")
562 {
563 if (is_library)
564 {
565 jar_header_fragment.copy (m_output_file, constituent.variables, 3,
566 &m_CONSTITUENT,
567 &m_CONSTITUENTSUFFIX,
568 &m_OBJS);
569 }
570 else
571 {
572 java_header_fragment.copy (m_output_file, constituent.variables, 3,
573 &m_CONSTITUENT,
574 &m_CONSTITUENTSUFFIX,
575 &m_OBJS);
576 }
577 }
578 else
579 {
580 if (is_library)
581 {
582 library_header_fragment.copy (m_output_file, constituent.variables, 3,
583 &m_CONSTITUENT,
584 &m_CONSTITUENTSUFFIX,
585 &m_PROTOTARGET);
586 }
587 else
588 {
589 application_header_fragment.copy (m_output_file, constituent.variables, 3,
590 &m_CONSTITUENT,
591 &m_CONSTITUENTSUFFIX,
592 &m_PROTOTARGET);
593 }
594 }
595
596
597 //----------------------------------------------------
598 //
599 // Preparing prototype files.
600 //
601 //----------------------------------------------------
602
603 //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
604 if (need_prototypes)
605 {
606 for (i = 0; i < m_source_files.size (); i++)
607 {
608 const SourceFile& file = m_source_files[i];
609 Language& language = file.language ();
610 if (language.prototypes)
611 {
612 prepare_proto_file (file.name ());
613 }
614 }
615
616 if (m_PROTOSTAMPS != "")
617 {
618 protos_header_fragment.copy (m_output_file, constituent.variables, 3,
619 &m_CONSTITUENT,
620 &m_CONSTITUENTSUFFIX,
621 &m_PROTOSTAMPS);
622 }
623
624 if (protonames != "")
625 {
626 for (i = 0; i < m_source_files.size (); i++)
627 {
628 const SourceFile& file = m_source_files[i];
629 Language& language = file.language ();
630 if (language.prototypes)
631 {
632 proto_file_action (file.name (), constituent);
633 }
634 }
635 }
636 }
637
638 //----------------------------------------------------
639 //
640 // Preparing the library.
641 //
642 //----------------------------------------------------
643
644 if (m_OBJS != "")
645 {
646 if (m_LINKMACRO == "java")
647 {
648 if (is_library)
649 {
650 cmt_string classes = m_OBJS.value;
651
652 classes.replace_all ("$(javabin)", "");
653 classes.replace_all (srcdir.c_str (), "");
654
655 m_CLASSES = classes;
656
657 jar_fragment.copy (m_output_file, constituent.variables, 4,
658 &m_CONSTITUENT,
659 &m_CONSTITUENTSUFFIX,
660 &m_OBJS,
661 &m_CLASSES);
662 }
663 }
664 else
665 {
666 if (is_library)
667 {
668 if (constituent.no_share)
669 {
670 library_no_share_fragment.copy (m_output_file, constituent.variables, 3,
671 &m_CONSTITUENT,
672 &m_CONSTITUENTSUFFIX,
673 &m_OBJS);
674 }
675 else
676 {
677 library_fragment.copy (m_output_file, constituent.variables, 3,
678 &m_CONSTITUENT,
679 &m_CONSTITUENTSUFFIX,
680 &m_OBJS);
681 }
682 }
683 else
684 {
685 application_fragment.copy (m_output_file, constituent.variables, 4,
686 &m_CONSTITUENT,
687 &m_CONSTITUENTSUFFIX,
688 &m_OBJS,
689 &m_LINKMACRO);
690 }
691 }
692 }
693
694 if (constituent.build_triggers)
695 {
696 dependencies_and_triggers_fragment.copy (m_output_file,
697 constituent.variables, 3,
698 &m_CONSTITUENT,
699 &m_CONSTITUENTSUFFIX,
700 &m_LINE);
701 }
702 else
703 {
704 dependencies_fragment.copy (m_output_file,
705 constituent.variables, 3,
706 &m_CONSTITUENT,
707 &m_CONSTITUENTSUFFIX,
708 &m_LINE);
709 }
710
711 //----------------------------------------------------
712 //
713 // Building actual individual targets.
714 //
715 //----------------------------------------------------
716
717 for (i = 0; i < m_source_files.size (); i++)
718 {
719 SourceFile& file = m_source_files[i];
720 Language& language = file.language ();
721
722 if (language == "java")
723 {
724 java_file_action (file, constituent);
725 }
726 else
727 {
728 module_file_action (file, constituent);
729 }
730 }
731
732 if (m_PACKOS9)
733 {
734 if (os9sources != "")
735 {
736 //
737 // Generate transfers to the OS9 area.
738 //
739
740 m_ALLOS9SOURCES = "";
741 allsources = "";
742 }
743 }
744
745 /*
746 for file in `cmt_sort_line.csh ${os9sources}` ; do
747 if test `echo ${file} | grep '$(src)'` ; then
748 name=`echo ${file} | sed 's#$(src)##'`
749 ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
750 allsources="${allsources} ${file}"
751 elif test `echo ${file} | grep '$(inc)'` ; then
752 name=`echo ${file} | sed 's#$(inc)##'`
753 ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
754 allsources="${allsources} ${file}"
755 fi
756 done
757
758 if test ! "${ALLOS9SOURCES}" = "" ; then
759
760 sed -e "`subs_vars ALLOS9SOURCES`" \
761 ${os9_header_fragment} \
762 >>${output}
763
764 for FULLNAME in ${allsources} ; do
765
766 NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'`
767
768 sed -e "`subs_vars NAME FULLNAME`" \
769 ${os9_fragment} \
770 >>${output}
771
772 done
773 fi
774 fi
775 fi
776 */
777
778 //
779 // Generate package cleanup operations.
780 //
781
782 cleanup_header_fragment.copy (m_output_file, constituent.variables, 2,
783 &m_CONSTITUENT,
784 &m_CONSTITUENTSUFFIX);
785
786 //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
787 if (need_prototypes)
788 {
789 if (protos != "")
790 {
791 m_FULLNAME = protos;
792 cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
793 m_FULLNAME = m_PROTOSTAMPS;
794 cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
795 }
796 }
797
798 if (m_LINKMACRO == "java")
799 {
800 cleanup_java_fragment.copy (m_output_file, constituent.variables, 1, &m_OBJS);
801
802 if (!is_library)
803 {
804 if (constituent.need_check)
805 {
806 check_java_fragment.copy (m_output_file, constituent.variables, 2,
807 &m_CONSTITUENT,
808 &m_CONSTITUENTSUFFIX);
809 }
810 }
811 }
812 else
813 {
814 if (is_library)
815 {
816 cleanup_library_fragment.copy (m_output_file, constituent.variables, 2,
817 &m_CONSTITUENT,
818 &m_CONSTITUENTSUFFIX);
819 }
820 else
821 {
822 cleanup_application_fragment.copy (m_output_file, constituent.variables, 2,
823 &m_CONSTITUENT,
824 &m_CONSTITUENTSUFFIX);
825 if (m_OBJS != "")
826 {
827 cleanup_objects_fragment.copy (m_output_file, constituent.variables, 3,
828 &m_OBJS,
829 &m_CONSTITUENT,
830 &m_CONSTITUENTSUFFIX);
831 }
832
833 if (constituent.need_check)
834 {
835 check_application_fragment.copy (m_output_file, constituent.variables, 2,
836 &m_CONSTITUENT,
837 &m_CONSTITUENTSUFFIX);
838 }
839 }
840 }
841
842 terminate ();
843}
844
845//--------------------------------------------------
846DocumentGenerator::DocumentGenerator ()
847{
848 document_header_fragment.set ("document_header");
849}
850
851//--------------------------------------------------
852void DocumentGenerator::reset ()
853{
854 AnyDocumentGenerator::reset ();
855 document_header_fragment.reset ();
856}
857
858//--------------------------------------------------
859void DocumentGenerator::build (const cmt_string& package,
860 const Constituent& constituent)
861{
862 static cmt_string names;
863 static cmt_string output_dir;
864 static cmt_string name;
865 static cmt_string full_name;
866 static cmt_string compressed_name;
867 static cmt_string suffix;
868 static cmt_string output_suffix;
869 static cmt_string fragment_suffix;
870
871 reset ();
872
873 if (!prepare_output (package, constituent)) return;
874
875 is_library = false;
876 is_application = false;
877 m_GENERATOR = constituent.generator;
878 m_TITLE = "Document";
879
880 int i;
881
882 cout << m_TITLE << " " << m_CONSTITUENT << endl;
883
884 //
885 // Prepare the include paths.
886 //
887
888 const CmtSystem::cmt_string_vector& includes = constituent.includes;
889
890 for (i = 0; i < includes.size (); i++)
891 {
892 const cmt_string& subdir = includes[i];
893
894 m_PACKINCLUDES += " -I";
895 m_PACKINCLUDES += subdir;
896 }
897
898 //
899 // Get the fragment associated with the document style
900 //
901
902 FragmentHandle fragment (m_GENERATOR);
903
904 fragment_suffix = fragment.suffix ();
905
906 output_suffix = ".";
907
908 if (fragment_suffix == "")
909 {
910 output_suffix += fragment.name ();
911 }
912 else
913 {
914 output_suffix += fragment_suffix;
915 }
916
917 //
918 // Scan the sources.
919 //
920
921 const CmtSystem::cmt_string_vector& sources = constituent.modules;
922 const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
923 const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
924
925 m_LINE = "";
926
927 for (i = 0; i < sources.size (); i++)
928 {
929 cmt_string& file = sources[i];
930
931 set_full_name (full_name, file);
932 if (full_name == "") continue;
933
934 CmtSystem::compress_path (full_name, compressed_name);
935 full_name = compressed_name;
936
937 static CmtSystem::cmt_string_vector files;
938
939 int count = get_all_files (full_name, excludes, selects, files);
940
941 filter_path (full_name);
942
943 if (count > 0)
944 {
945 m_LINE += full_name;
946 m_LINE += " ";
947 }
948
949 for (int j = 0; j < files.size (); j++)
950 {
951 const cmt_string& name = files[j];
952
953 if (name != "")
954 {
955 analyze_file (name, constituent.name, output_suffix);
956 }
957 }
958 }
959
960 fill_outputs ();
961
962 prepare_use_context ();
963
964 m_DATE = CmtSystem::now ();
965 m_USER = CmtSystem::user ();
966 m_PACKAGE = package;
967
968 if (constituent.has_target_tag)
969 {
970 m_HASTARGETTAG = "has_target_tag";
971 }
972 else
973 {
974 m_HASTARGETTAG = "has_no_target_tag";
975 }
976
977 make_header_fragment.copy (m_output_file, constituent.variables, 7,
978 &m_TITLE,
979 &m_CONSTITUENT,
980 &m_CONSTITUENTSUFFIX,
981 &m_USER,
982 &m_DATE,
983 &m_PACKAGE,
984 &m_HASTARGETTAG);
985
986 const cmt_string& header = fragment.header ();
987
988 //
989 // If the document type specifies a header, use it .
990 // otherwise, use the default document header fragment.
991 //
992 if (header != "")
993 {
994 FragmentHandle header_fragment (header);
995 header_fragment.copy (m_output_file, constituent.variables, 3,
996 &m_CONSTITUENT,
997 &m_CONSTITUENTSUFFIX,
998 &m_OBJS);
999 }
1000 else
1001 {
1002 document_header_fragment.copy (m_output_file, constituent.variables, 3,
1003 &m_CONSTITUENT,
1004 &m_CONSTITUENTSUFFIX,
1005 &m_OBJS);
1006 }
1007
1008 if (fragment.need_dependencies ())
1009 {
1010 dependencies_fragment.copy (m_output_file, constituent.variables, 3,
1011 &m_CONSTITUENT,
1012 &m_CONSTITUENTSUFFIX,
1013 &m_LINE);
1014 }
1015 else
1016 {
1017 for (i = 0; i < sources.size (); i++)
1018 {
1019 cmt_string& file = sources[i];
1020
1021 set_full_name (full_name, file);
1022 if (full_name == "") continue;
1023
1024 CmtSystem::compress_path (full_name, compressed_name);
1025 full_name = compressed_name;
1026
1027 static CmtSystem::cmt_string_vector files;
1028
1029 get_all_files (full_name, excludes, selects, files);
1030
1031 for (int j = 0; j < files.size (); j++)
1032 {
1033 const cmt_string& name = files[j];
1034
1035 if (name != "")
1036 {
1037 static cmt_string s;
1038 static cmt_string n;
1039
1040 CmtSystem::get_dot_suffix (name, s);
1041 CmtSystem::basename (name, s, n);
1042 CmtSystem::get_suffix (name, s);
1043
1044 fprintf (m_output_file, "%s_%s_dependencies = %s\n",
1045 n.c_str (),
1046 s.c_str (),
1047 name.c_str ());
1048 }
1049 }
1050 }
1051 }
1052
1053 m_SUFFIX = fragment_suffix;
1054 for (i = 0; i < m_source_files.size (); i++)
1055 {
1056 SourceFile& file = m_source_files[i];
1057 const cmt_string& file_name = file.name ();
1058 m_FULLNAME = file_name;
1059 CmtSystem::get_dot_suffix (file_name, suffix);
1060 CmtSystem::basename (file_name, suffix, m_NAME.value);
1061 CmtSystem::dirname (file_name, m_FILEPATH.value);
1062 if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
1063 filter_path (m_FILEPATH.value);
1064 CmtSystem::basename (file_name, m_FILENAME.value);
1065 CmtSystem::get_dot_suffix (m_FILENAME.value, m_FILESUFFIX.value);
1066
1067 if (!CmtSystem::test_file (file_name) && !CmtSystem::test_directory (file_name))
1068 {
1069 cerr << "#CMT> Warning: Source file " << file_name << " not found" << endl;
1070 }
1071
1072 filter_path (m_FULLNAME.value);
1073
1074 fragment.copy (m_output_file, constituent.variables, 8,
1075 &m_FILEPATH,
1076 &m_SUFFIX,
1077 &m_CONSTITUENT,
1078 &m_CONSTITUENTSUFFIX,
1079 &m_FILENAME,
1080 &m_NAME,
1081 &m_FULLNAME,
1082 &m_FILESUFFIX);
1083 }
1084
1085 const cmt_string& trailer = fragment.trailer ();
1086 if (trailer != "")
1087 {
1088 FragmentHandle trailer_fragment (trailer);
1089 trailer_fragment.copy (m_output_file, constituent.variables, 3,
1090 &m_CONSTITUENT,
1091 &m_CONSTITUENTSUFFIX,
1092 &m_OBJS);
1093 }
1094
1095 //
1096 // Generate package cleanup operations.
1097 //
1098
1099 cleanup_header_fragment.copy (m_output_file, constituent.variables, 2,
1100 &m_CONSTITUENT,
1101 &m_CONSTITUENTSUFFIX);
1102
1103 terminate ();
1104}
1105
1106//--------------------------------------------------
1107bool DocumentGenerator::analyze_file (const cmt_string& file,
1108 const cmt_string& constituent_name,
1109 const cmt_string& output_suffix)
1110{
1111 static cmt_string output_dir;
1112 static cmt_string suffix;
1113 static cmt_string name;
1114 static cmt_string obj;
1115
1116 if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file))
1117 {
1118 cerr << "#CMT> Warning: Source file " << file << " not found" << endl;
1119 }
1120
1121 CmtSystem::dirname (file, output_dir);
1122 output_dir += CmtSystem::file_separator ();
1123
1124 filter_path (output_dir);
1125
1126 CmtSystem::get_suffix (file, suffix);
1127 CmtSystem::basename (file, suffix, name);
1128
1129 //obj = output_dir;
1130 obj = "$(";
1131 obj += constituent_name;
1132 obj += "_output)";
1133 obj += name;
1134 obj += output_suffix;
1135
1136 SourceFile& source = m_source_files.add ();
1137 source.set (file, Language::null (), obj);
1138
1139 return (true);
1140}
1141
1142ReadmeGenerator::ReadmeGenerator ()
1143{
1144 readme_header_fragment.set ("readme_header");
1145 readme_fragment.set ("readme");
1146 readme_doc_fragment.set ("readme_doc");
1147 readme_use_fragment.set ("readme_use");
1148 readme_trailer_fragment.set ("readme_trailer");
1149}
1150
1151void ReadmeGenerator::reset ()
1152{
1153 CmtGenerator::reset ();
1154
1155 readme_header_fragment.reset ();
1156 readme_fragment.reset ();
1157 readme_doc_fragment.reset ();
1158 readme_use_fragment.reset ();
1159 readme_trailer_fragment.reset ();
1160}
1161
1162//--------------------------------------------------
1163void ReadmeGenerator::build (const CmtSystem::cmt_string_vector& arguments)
1164{
1165 reset ();
1166
1167 m_PACKAGE = Cmt::get_current_package ();
1168 m_VERSION = Cmt::get_current_version ();
1169 m_DATE = CmtSystem::now ();
1170 m_USER = CmtSystem::user ();
1171
1172 cmt_string url;
1173 cmt_string doc;
1174
1175 for (int i = 0; i < arguments.size (); i++)
1176 {
1177 cmt_string arg = arguments[i];
1178
1179 if (arg.substr (0, 5) == "-url=")
1180 {
1181 arg.substr (5, url);
1182 }
1183 else if (arg.substr (0, 5) == "-doc=")
1184 {
1185 arg.substr (5, doc);
1186 }
1187 }
1188
1189 m_output_file_name = cmtdir + "README.html";
1190
1191 m_output_file = fopen (m_output_file_name.c_str (), "wb");
1192 if (m_output_file != NULL)
1193 {
1194 readme_header_fragment.copy (m_output_file, 2,
1195 &m_PACKAGE, &m_VERSION);
1196
1197 if (doc != "")
1198 {
1199 m_DOCPATH = doc;
1200 readme_doc_fragment.copy (m_output_file, 3,
1201 &m_PACKAGE,
1202 &m_VERSION,
1203 &m_DOCPATH);
1204 }
1205
1206 readme_fragment.copy (m_output_file, 2,
1207 &m_PACKAGE,
1208 &m_VERSION);
1209
1210 int number;
1211 const Use::UsePtrVector& uses = Use::get_ordered_uses ();
1212
1213 for (number = 0; number < uses.size (); number++)
1214 {
1215 const Use* use = uses[number];
1216
1217 if (use == 0) continue;
1218 if (use->discarded) continue;
1219
1220 Package* p = use->get_package ();
1221 if (p->is_cmt ()) continue;
1222
1223 cmt_string selected_path;
1224
1225 if (url == "")
1226 {
1227 selected_path = use->real_path;
1228
1229 if (use->specified_path != "")
1230 {
1231 int pos = selected_path.find_last_of (use->specified_path);
1232 if (pos != cmt_string::npos)
1233 {
1234 selected_path.erase (pos);
1235 }
1236 }
1237 }
1238 else
1239 {
1240 selected_path = url;
1241
1242 if (use->specified_path != "")
1243 {
1244 selected_path += CmtSystem::file_separator ();
1245 }
1246 }
1247
1248 m_PACKAGEPATH = selected_path;
1249 m_PACKAGEPREFIX = use->specified_path;
1250 m_PACKAGE = use->get_package_name ();
1251 m_VERSION = use->version;
1252 m_MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt";
1253 readme_use_fragment.copy (m_output_file, 5,
1254 &m_PACKAGEPATH,
1255 &m_PACKAGEPREFIX,
1256 &m_PACKAGE,
1257 &m_VERSION,
1258 &m_MGRSTYLE);
1259 }
1260
1261 m_PACKAGE = Cmt::get_current_package ();
1262 m_VERSION = Cmt::get_current_version ();
1263 readme_trailer_fragment.copy (m_output_file, 4,
1264 &m_PACKAGE,
1265 &m_VERSION,
1266 &m_DATE,
1267 &m_USER);
1268
1269 terminate ();
1270 }
1271}
1272
1273//--------------------------------------------------
1274class Prototyper : public FAwk
1275{
1276public:
1277 Prototyper (bool static_functions = false) :
1278 m_static_functions(static_functions)
1279 {
1280 if (m_static_functions)
1281 {
1282 m_suffix = "_static.phnew";
1283 m_define_suffix = "_static_ph";
1284 }
1285 else
1286 {
1287 m_suffix = ".phnew";
1288 m_define_suffix = "_ph";
1289 }
1290 }
1291
1292 void begin ()
1293 {
1294 m_running = false;
1295
1296 static cmt_string suffix;
1297 static cmt_string name;
1298
1299 CmtSystem::get_dot_suffix (m_file_name, suffix);
1300 CmtSystem::basename (m_file_name, suffix, name);
1301
1302 m_out_file_name = "";
1303
1304 if (m_dir_name != "")
1305 {
1306 m_out_file_name = m_dir_name;
1307 m_out_file_name += CmtSystem::file_separator ();
1308 }
1309
1310 m_out_file_name += name;
1311 m_out_file_name += m_suffix;
1312
1313 CmtSystem::basename (m_file_name, suffix, m_file_name);
1314
1315 m_output = fopen (m_out_file_name.c_str (), "wb");
1316
1317 if (m_output != 0)
1318 {
1319 fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (),
1320 m_define_suffix.c_str ());
1321 fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (),
1322 m_define_suffix.c_str ());
1323
1324 fprintf (m_output, "\n");
1325 fprintf (m_output, "#ifdef __cplusplus\n");
1326 fprintf (m_output, "extern \"C\" {\n");
1327 fprintf (m_output, "#endif\n");
1328 fprintf (m_output, "\n");
1329 }
1330 else
1331 {
1332 stop ();
1333 }
1334 }
1335
1336 void filter (const cmt_string& line)
1337 {
1338 char c = line[0];
1339
1340 if (!m_running)
1341 {
1342 if ((c == ' ') ||
1343 (c == '/') ||
1344 (c == '|') ||
1345 (c == '\t') ||
1346 (c == '#')) return;
1347 if (line.find ('(') == cmt_string::npos)
1348 {
1349 m_prev_line = line;
1350 return;
1351 }
1352
1353 m_running = true;
1354 m_full_line = line;
1355 m_full_line.replace ("(", " (");
1356
1357 static CmtSystem::cmt_string_vector words;
1358
1359 CmtSystem::split (m_full_line, " \t", words);
1360
1361 const cmt_string& second = words[1];
1362 if (second[0] == '(')
1363 {
1364 m_full_line = m_prev_line;
1365 m_full_line += " ";
1366 m_full_line += line;
1367
1368 m_prev_line = "";
1369 }
1370 }
1371 else
1372 {
1373 m_full_line += line;
1374 }
1375 if (line.find (')') == cmt_string::npos) return;
1376 m_running = false;
1377
1378 if (m_full_line.find (';') != cmt_string::npos) return;
1379 if (m_full_line.find ("::") != cmt_string::npos) return;
1380 if (m_full_line.find ('<') != cmt_string::npos) return;
1381 if (m_full_line.find ('>') != cmt_string::npos) return;
1382 if (m_full_line.find ('{') != cmt_string::npos) return;
1383 if (m_full_line.find ('}') != cmt_string::npos) return;
1384 if (m_full_line.find ("typedef") != cmt_string::npos) return;
1385 if (m_full_line.find ("yy") != cmt_string::npos) return;
1386 if (m_full_line.find ("YY") != cmt_string::npos) return;
1387 if (m_static_functions)
1388 {
1389 if (m_full_line.find ("static") == cmt_string::npos) return;
1390 }
1391 else
1392 {
1393 if (m_full_line.find ("static") != cmt_string::npos) return;
1394 }
1395
1396 m_full_line += ";";
1397
1398 if (m_output != 0)
1399 {
1400 fprintf (m_output, "%s\n", m_full_line.c_str ());
1401 }
1402 }
1403
1404 void end ()
1405 {
1406 if (m_output != 0)
1407 {
1408 fprintf (m_output, "\n");
1409 fprintf (m_output, "#ifdef __cplusplus\n");
1410 fprintf (m_output, "}\n");
1411 fprintf (m_output, "#endif\n");
1412 fprintf (m_output, "\n");
1413 fprintf (m_output, "#endif\n");
1414 fprintf (m_output, "\n");
1415
1416 fclose (m_output);
1417 }
1418
1419 CmtGenerator::check (m_out_file_name);
1420 }
1421
1422private:
1423 bool m_running;
1424 cmt_string m_out_file_name;
1425 FILE* m_output;
1426 bool m_static_functions;
1427 cmt_string m_full_line;
1428 cmt_string m_prev_line;
1429 cmt_string m_suffix;
1430 cmt_string m_define_suffix;
1431};
1432//--------------------------------------------------
1433
1434//--------------------------------------------------
1435void PrototypeGenerator::build (const cmt_string& file_name)
1436{
1437 Prototyper prototyper;
1438
1439 reset ();
1440
1441 prototyper.run (file_name);
1442}
1443
1444//--------------------------------------------------
1445void DefaultMakefileGenerator::build ()
1446{
1447 cmt_string makefile;
1448
1449 //reset ();
1450
1451 //--- Build a simple Makefile if none is installed
1452
1453#ifndef WIN32
1454
1455 bool need_makefile = false;
1456
1457 makefile = cmtdir + "Makefile";
1458
1459 if (!CmtSystem::test_file (makefile))
1460 {
1461 need_makefile = true;
1462 }
1463 else
1464 {
1465 static cmt_string s;
1466
1467 s.read (makefile);
1468 if ((s.find ("METHODSROOT") != cmt_string::npos) ||
1469 (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos))
1470 {
1471 static cmt_string backup = makefile;
1472 backup += "_backup";
1473
1474 makefile += ".cmt";
1475
1476 if (!CmtSystem::test_file (makefile))
1477 {
1478 FILE* file = fopen (backup.c_str (), "wb");
1479 if (file != NULL)
1480 {
1481 cerr << "# " << endl;
1482 cerr << "#CMT> Warning: " << endl;
1483 cerr << "# A Makefile already exists "
1484 "but it does not provides " << endl;
1485 cerr << "# the recommended features "
1486 "for a full benefit of CMT" << endl;
1487 cerr << "# " << endl;
1488 cerr << "# CMT is now building "
1489 "a new 'Makefile.cmt' which you can use" << endl;
1490 cerr << "# to upgrade your current one." << endl;
1491 cerr << "# " << endl;
1492
1493 s.write (file);
1494 fclose (file);
1495
1496 need_makefile = true;
1497 }
1498 }
1499 }
1500 }
1501
1502 if (need_makefile)
1503 {
1504 FILE* file = fopen (makefile.c_str (), "wb");
1505 if (file != NULL)
1506 {
1507 fprintf (file, "include $(CMTROOT)/src/Makefile.header\n");
1508 fprintf (file, "\n");
1509 fprintf (file, "include $(CMTROOT)/src/constituents.make\n");
1510 fprintf (file, "\n");
1511 fclose (file);
1512 }
1513 }
1514
1515#endif
1516
1517#ifdef WIN32
1518
1519 makefile = cmtdir + "NMake";
1520
1521 if (Cmt::get_debug ())
1522 {
1523 cout << "DefaultMakefileGenerator::build> pwd=" << CmtSystem::pwd () << " cmtdir=" << cmtdir << endl;
1524 }
1525
1526 if (!CmtSystem::test_file (makefile))
1527 {
1528 FILE* file = fopen (makefile.c_str (), "wb");
1529 if (file != NULL)
1530 {
1531 fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n");
1532 fprintf (file, "\n");
1533 fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n");
1534 fprintf (file, "\n");
1535 fclose (file);
1536 }
1537 }
1538
1539#endif
1540
1541}
1542
1543MSDEVGenerator::MSDEVGenerator ()
1544{
1545 dsw_header_fragment.set ("dsw_header");
1546 dsw_project_fragment.set ("dsw_project");
1547 dsw_all_project_header_fragment.set ("dsw_all_project_header");
1548 dsw_all_project_dependency_fragment.set ("dsw_all_project_dependency");
1549 dsw_all_project_trailer_fragment.set ("dsw_all_project_trailer");
1550 dsw_trailer_fragment.set ("dsw_trailer");
1551
1552 dsp_all_fragment.set ("dsp_all");
1553 dsp_library_header_fragment.set ("dsp_library_header");
1554 dsp_application_header_fragment.set ("dsp_application_header");
1555 dsp_windows_header_fragment.set ("dsp_windows_header");
1556 dsp_contents_fragment.set ("dsp_contents");
1557 dsp_trailer_fragment.set ("dsp_trailer");
1558}
1559
1560void MSDEVGenerator::reset ()
1561{
1562 CmtGenerator::reset ();
1563
1564 dsw_header_fragment.reset ();
1565 dsw_project_fragment.reset ();
1566 dsw_all_project_header_fragment.reset ();
1567 dsw_all_project_dependency_fragment.reset ();
1568 dsw_all_project_trailer_fragment.reset ();
1569 dsw_trailer_fragment.reset ();
1570
1571 dsp_all_fragment.reset ();
1572 dsp_library_header_fragment.reset ();
1573 dsp_application_header_fragment.reset ();
1574 dsp_windows_header_fragment.reset ();
1575 dsp_contents_fragment.reset ();
1576 dsp_trailer_fragment.reset ();
1577
1578 CmtSystem::cd (Cmt::get_current_dir ());
1579
1580 cmt_string branch = CmtSystem::current_branch ();
1581
1582 if ((branch == "mgr") || (branch == "cmt"))
1583 {
1584#ifdef WIN32
1585 msdevdir = "..";
1586 msdevdir += CmtSystem::file_separator ();
1587 msdevdir += "Visual";
1588
1589 if (!CmtSystem::test_directory (msdevdir))
1590 {
1591 CmtSystem::mkdir (msdevdir);
1592 }
1593
1594 msdevdir += CmtSystem::file_separator ();
1595#endif
1596 }
1597 else
1598 {
1599#ifdef WIN32
1600 msdevdir = ".";
1601 msdevdir += CmtSystem::file_separator ();
1602#endif
1603 }
1604
1605}
1606
1607int MSDEVGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
1608{
1609 reset ();
1610
1611 const cmt_string& package = Cmt::get_current_package ();
1612
1613 m_output_file_name = msdevdir + package + ".dswnew";
1614
1615 m_output_file = fopen (m_output_file_name.c_str (), "wb");
1616 if (m_output_file != NULL)
1617 {
1618 m_PACKAGE = package;
1619 dsw_header_fragment.wincopy (m_output_file, 1,
1620 &m_PACKAGE);
1621
1622 int i;
1623
1624 dsw_all_project_header_fragment.wincopy (m_output_file, 1,
1625 &m_PACKAGE);
1626
1627 for (i = 0; i < constituents.size (); i++)
1628 {
1629 const Constituent& constituent = constituents[i];
1630
1631 if (constituent.type == Library)
1632 {
1633 m_CONSTITUENT = constituent.name;
1634 m_CONSTITUENTSUFFIX = constituent.suffix;
1635 dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1636 &m_PACKAGE,
1637 &m_CONSTITUENT,
1638 &m_CONSTITUENTSUFFIX);
1639 }
1640 else
1641 {
1642 m_CONSTITUENT = constituent.name;
1643 m_CONSTITUENTSUFFIX = constituent.suffix;
1644 dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1645 &m_PACKAGE,
1646 &m_CONSTITUENT,
1647 &m_CONSTITUENTSUFFIX);
1648 }
1649
1650 }
1651
1652 dsw_all_project_trailer_fragment.wincopy (m_output_file,
1653 1, &m_PACKAGE);
1654
1655 for (i = 0; i < constituents.size (); i++)
1656 {
1657 const Constituent& constituent = constituents[i];
1658
1659 if (constituent.type == Library)
1660 {
1661 m_CONSTITUENT = constituent.name;
1662 m_CONSTITUENTSUFFIX = constituent.suffix;
1663 dsw_project_fragment.wincopy (m_output_file,
1664 constituent.variables, 3,
1665 &m_PACKAGE,
1666 &m_CONSTITUENT,
1667 &m_CONSTITUENTSUFFIX);
1668 }
1669 else
1670 {
1671 m_CONSTITUENT = constituent.name;
1672 m_CONSTITUENTSUFFIX = constituent.suffix;
1673 dsw_project_fragment.wincopy (m_output_file, constituent.variables, 3,
1674 &m_PACKAGE,
1675 &m_CONSTITUENT,
1676 &m_CONSTITUENTSUFFIX);
1677 }
1678 }
1679
1680 dsw_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1681
1682 terminate ();
1683 }
1684
1685 m_output_file_name = msdevdir + "all.dspnew";
1686
1687 m_output_file = fopen (m_output_file_name.c_str (), "wb");
1688 if (m_output_file != NULL)
1689 {
1690 dsp_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1691 terminate ();
1692 }
1693
1694 return (0);
1695}
1696
1697//--------------------------------------------------
1698int MSDEVGenerator::build_project (const Constituent& constituent)
1699{
1700 reset ();
1701
1702 const cmt_string& package = Cmt::get_current_package ();
1703 static cmt_string file;
1704 static cmt_string full_name;
1705 static cmt_string suffix;
1706
1707 int i;
1708
1709 m_CONSTITUENT = constituent.name;
1710 m_CONSTITUENTSUFFIX = constituent.suffix;
1711
1712 for (i = 0; i < constituent.includes.size (); i++)
1713 {
1714 const cmt_string& include = constituent.includes[i];
1715 m_PACKINCLUDES += " -I" + include;
1716 }
1717
1718 switch (constituent.type)
1719 {
1720 case Application:
1721 is_application = true;
1722 m_TITLE = "Application";
1723 break;
1724 case Library:
1725 is_library = true;
1726 m_TITLE = "Library";
1727 break;
1728 case Document:
1729 m_GENERATOR = constituent.generator;
1730 m_TITLE = "Document";
1731 break;
1732 }
1733
1734 m_PACKOS9 = constituent.need_OS9;
1735
1736 const CmtSystem::cmt_string_vector& sources = constituent.modules;
1737 const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
1738 const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
1739
1740 //--- Build the constituents fragment -----
1741
1742 m_output_file_name = msdevdir + m_CONSTITUENT + ".dspnew";
1743 m_output_file = fopen (m_output_file_name.c_str (), "wb");
1744
1745 if (m_output_file == NULL) return (0);
1746
1747 m_PACKAGE = package;
1748
1749 if (is_library)
1750 {
1751 if (constituent.no_share)
1752 {
1753 m_LIBRARYSUFFIX = "lib";
1754 }
1755 else
1756 {
1757 m_LIBRARYSUFFIX = "arc";
1758 }
1759
1760 dsp_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
1761 &m_PACKAGE,
1762 &m_CONSTITUENT,
1763 &m_CONSTITUENTSUFFIX,
1764 &m_LIBRARYSUFFIX);
1765 }
1766 else
1767 {
1768 if (constituent.windows)
1769 {
1770 dsp_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1771 &m_PACKAGE,
1772 &m_CONSTITUENT,
1773 &m_CONSTITUENTSUFFIX);
1774 }
1775 else
1776 {
1777 dsp_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1778 &m_PACKAGE,
1779 &m_CONSTITUENT,
1780 &m_CONSTITUENTSUFFIX);
1781 }
1782 }
1783
1784 for (i = 0; i < sources.size (); i++)
1785 {
1786 file = sources[i];
1787
1788 set_full_name (full_name, file);
1789 if (full_name == "") continue;
1790
1791 static CmtSystem::cmt_string_vector files;
1792
1793 get_all_files (full_name, excludes, selects, files);
1794
1795 for (int j = 0; j < files.size (); j++)
1796 {
1797 const cmt_string& name = files[j];
1798
1799 if (name != "")
1800 {
1801 m_FULLNAME = name;
1802
1803 if (m_output_file != NULL)
1804 {
1805 dsp_contents_fragment.wincopy (m_output_file, constituent.variables, 2,
1806 &m_PACKAGE,
1807 &m_FULLNAME);
1808 }
1809 }
1810 }
1811 }
1812
1813 if (m_output_file != NULL)
1814 {
1815 dsp_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
1816 &m_PACKAGE,
1817 &m_CONSTITUENT,
1818 &m_CONSTITUENTSUFFIX);
1819
1820 terminate ();
1821 }
1822
1823 return (0);
1824}
1825
1826
1827VSNETGenerator::VSNETGenerator ()
1828{
1829 sln_header_fragment.set ("sln_header");
1830 sln_project_fragment.set ("sln_project");
1831 sln_dependency_header_fragment.set ("sln_dependency_header");
1832 sln_dependency_project_fragment.set ("sln_dependency_project");
1833 sln_dependency_trailer_fragment.set ("sln_dependency_trailer");
1834 sln_project_config_fragment.set ("sln_project_config");
1835 sln_trailer_fragment.set ("sln_trailer");
1836
1837 vcproj_all_fragment.set ("vcproj_all");
1838 vcproj_library_header_fragment.set ("vcproj_library_header");
1839 vcproj_application_header_fragment.set ("vcproj_application_header");
1840 vcproj_windows_header_fragment.set ("vcproj_windows_header");
1841 vcproj_contents_fragment.set ("vcproj_contents");
1842 vcproj_directory_header_fragment.set ("vcproj_directory_header");
1843 vcproj_directory_trailer_fragment.set ("vcproj_directory_trailer");
1844 vcproj_trailer_fragment.set ("vcproj_trailer");
1845}
1846
1847void VSNETGenerator::reset ()
1848{
1849 CmtGenerator::reset ();
1850
1851 CmtSystem::cd (Cmt::get_current_dir ());
1852
1853 cmt_string branch = CmtSystem::current_branch ();
1854
1855 if ((branch == "mgr") || (branch == "cmt"))
1856 {
1857#ifdef WIN32
1858 vsnetdir = "..";
1859 vsnetdir += CmtSystem::file_separator ();
1860 vsnetdir += "Visual";
1861
1862 if (!CmtSystem::test_directory (vsnetdir))
1863 {
1864 CmtSystem::mkdir (vsnetdir);
1865 }
1866
1867 vsnetdir += CmtSystem::file_separator ();
1868#endif
1869 }
1870 else
1871 {
1872#ifdef WIN32
1873 vsnetdir = ".";
1874 vsnetdir += CmtSystem::file_separator ();
1875#endif
1876 }
1877}
1878
1879void VSNETGenerator::pseudoGUID (const cmt_string& a,
1880 const cmt_string& b,
1881 const cmt_string& c,
1882 cmt_string& d)
1883{
1884 char buf[64]; // make the guid in here
1885 static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1886 int k = 0;
1887 int i;
1888
1889 for (i = 0; (i < c.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = c[i];
1890 for (i = 0; (i < a.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = a[i];
1891 for (i = 0; (i < b.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = b[i];
1892 for (; k < sizeof(buf); ++k) buf[k] = 0;
1893
1894 // now use the buffer to format the output string
1895 // example: {3FE091FC-3738-4F2E-9723-E846B43F77AB}
1896 d = '{';
1897 k = 0;
1898
1899 for (i = 0; i < 4; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1900 for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1901 for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1902 for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1903 for (i = 0; i < 6; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '}';
1904}
1905
1906int VSNETGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
1907{
1908 reset ();
1909
1910 const cmt_string& package = Cmt::get_current_package ();
1911
1912 m_output_file_name = vsnetdir + package + ".slnnew";
1913
1914 Variable PACKAGE_GUID ("PACKAGE_GUID");
1915 Variable CONSTITUENT_GUID ("CONSTITUENT_GUID");
1916 Variable NUMBER ("NUMBER");
1917
1918 cmt_string guid;
1919 pseudoGUID (package, Cmt::get_current_version(), "", guid);
1920 PACKAGE_GUID = guid;
1921
1922 m_output_file = fopen (m_output_file_name.c_str (), "wb");
1923
1924 if (m_output_file != NULL)
1925 {
1926 m_PACKAGE = package;
1927 sln_header_fragment.wincopy (m_output_file, 2,
1928 &m_PACKAGE,
1929 &PACKAGE_GUID);
1930
1931 int i;
1932
1933 for (i = 0; i < constituents.size (); i++)
1934 {
1935 const Constituent& constituent = constituents[i];
1936
1937 pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
1938 CONSTITUENT_GUID = guid;
1939
1940 if (constituent.type == Library)
1941 {
1942 m_CONSTITUENT = constituent.name;
1943 m_CONSTITUENTSUFFIX = constituent.suffix;
1944 sln_project_fragment.wincopy (m_output_file,
1945 constituent.variables, 4,
1946 &m_PACKAGE,
1947 &m_CONSTITUENT,
1948 &PACKAGE_GUID,
1949 &CONSTITUENT_GUID);
1950 }
1951 else
1952 {
1953 m_CONSTITUENT = constituent.name;
1954 m_CONSTITUENTSUFFIX = constituent.suffix;
1955 sln_project_fragment.wincopy (m_output_file, constituent.variables, 4,
1956 &m_PACKAGE,
1957 &m_CONSTITUENT,
1958 &PACKAGE_GUID,
1959 &CONSTITUENT_GUID);
1960 }
1961 }
1962
1963 sln_dependency_header_fragment.wincopy (m_output_file,
1964 1, &m_PACKAGE);
1965
1966 for (i = 0; i < constituents.size (); i++)
1967 {
1968 const Constituent& constituent = constituents[i];
1969 pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
1970 CONSTITUENT_GUID = guid;
1971
1972 cmt_string num;
1973 num = (char)('0' + i);
1974 NUMBER = num;
1975 if (constituent.type == Library)
1976 {
1977 m_CONSTITUENT = constituent.name;
1978 m_CONSTITUENTSUFFIX = constituent.suffix;
1979
1980 sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
1981 &m_PACKAGE,
1982 &m_CONSTITUENT,
1983 &PACKAGE_GUID,
1984 &CONSTITUENT_GUID,
1985 &NUMBER);
1986 }
1987 else
1988 {
1989 m_CONSTITUENT = constituent.name;
1990 m_CONSTITUENTSUFFIX = constituent.suffix;
1991 sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
1992 &m_PACKAGE,
1993 &m_CONSTITUENT,
1994 &PACKAGE_GUID,
1995 &CONSTITUENT_GUID,
1996 &NUMBER);
1997 }
1998 }
1999
2000 sln_dependency_trailer_fragment.wincopy (m_output_file,
2001 1, &m_PACKAGE);
2002
2003 for (i = 0; i < constituents.size (); i++)
2004 {
2005 const Constituent& constituent = constituents[i];
2006 pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2007 CONSTITUENT_GUID = guid;
2008
2009 if (constituent.type == Library)
2010 {
2011 m_CONSTITUENT = constituent.name;
2012 m_CONSTITUENTSUFFIX = constituent.suffix;
2013 sln_project_config_fragment.wincopy (m_output_file,
2014 constituent.variables, 3,
2015 &m_PACKAGE,
2016 &m_CONSTITUENT,
2017 &CONSTITUENT_GUID);
2018 }
2019 else
2020 {
2021 m_CONSTITUENT = constituent.name;
2022 m_CONSTITUENTSUFFIX = constituent.suffix;
2023 sln_project_config_fragment.wincopy (m_output_file, constituent.variables, 3,
2024 &m_PACKAGE,
2025 &m_CONSTITUENT,
2026 &CONSTITUENT_GUID);
2027 }
2028 }
2029
2030 sln_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
2031
2032 terminate ();
2033 }
2034
2035 m_output_file_name = vsnetdir + "all.vcprojnew";
2036
2037 m_output_file = fopen (m_output_file_name.c_str (), "wb");
2038 if (m_output_file != NULL)
2039 {
2040 vcproj_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
2041
2042 terminate ();
2043 }
2044
2045 return (0);
2046}
2047
2048int VSNETGenerator::build_project (const Constituent& constituent)
2049{
2050 reset ();
2051
2052 const cmt_string& package = Cmt::get_current_package();
2053 static cmt_string file;
2054 static cmt_string full_name;
2055 static cmt_string suffix;
2056
2057 static Variable GUID("GUID");
2058 int i;
2059
2060 // Directory Support
2061 int dir_pos;
2062 int file_pos;
2063 int src_pos;
2064 int iSFFilter = 0;
2065 cmt_string directory;
2066 cmt_string new_dir;
2067 bool need_trailer = false;
2068
2069 m_CONSTITUENT = constituent.name;
2070 // make up a pseudo-GUID from the constituent-pacakge-version combination
2071
2072 cmt_string guid;
2073 pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2074
2075 GUID = guid;
2076
2077 for (i = 0; i < constituent.includes.size (); i++)
2078 {
2079 const cmt_string& include = constituent.includes[i];
2080 m_PACKINCLUDES += " -I" + include;
2081 }
2082
2083 switch (constituent.type)
2084 {
2085 case Application:
2086 is_application = true;
2087 m_TITLE = "Application";
2088 break;
2089 case Library:
2090 is_library = true;
2091 m_TITLE = "Library";
2092 break;
2093 case Document:
2094 m_GENERATOR = constituent.generator;
2095 m_TITLE = "Document";
2096 break;
2097 }
2098
2099 m_PACKOS9 = constituent.need_OS9;
2100
2101 const CmtSystem::cmt_string_vector& sources = constituent.modules;
2102 const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
2103 const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
2104
2105 //--- Build the constituents fragment -----
2106 cmt_string output;
2107
2108 m_output_file_name = vsnetdir + m_CONSTITUENT + ".vcprojnew";
2109 m_output_file = fopen (m_output_file_name.c_str (), "wb");
2110
2111 if (m_output_file == NULL) return (0);
2112
2113 m_PACKAGE = package;
2114
2115 if (is_library)
2116 {
2117 if (constituent.no_share)
2118 {
2119 m_LIBRARYSUFFIX = "lib";
2120 }
2121 else
2122 {
2123 m_LIBRARYSUFFIX = "arc";
2124 }
2125
2126 vcproj_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
2127 &m_PACKAGE,
2128 &m_CONSTITUENT,
2129 &GUID,
2130 &m_LIBRARYSUFFIX);
2131 }
2132 else
2133 {
2134 if (constituent.windows)
2135 {
2136 vcproj_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2137 &m_PACKAGE,
2138 &m_CONSTITUENT,
2139 &GUID);
2140 }
2141 else
2142 {
2143 vcproj_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2144 &m_PACKAGE,
2145 &m_CONSTITUENT,
2146 &GUID);
2147 }
2148 }
2149
2150 for (i = 0; i < sources.size (); i++)
2151 {
2152 file = sources[i];
2153
2154 set_full_name (full_name, file);
2155 if (full_name == "") continue;
2156
2157 static CmtSystem::cmt_string_vector files;
2158
2159 get_all_files (full_name, excludes, selects, files);
2160
2161 for (int j = 0; j < files.size (); j++)
2162 {
2163 const cmt_string& name = files[j];
2164
2165 if (name != "")
2166 {
2167 m_FULLNAME = name;
2168
2169 // Add Directory Support here
2170 // Step 1: Parse into "..\src\" "directory" "\filename.cxx"
2171
2172 // find ..\ ;
2173 src_pos = name.find('\\');
2174 // Finds ..\src\ ;
2175 dir_pos = name.find(src_pos+1, '\\') + 1;
2176 // Finds ..\src\..\astro\ ;
2177 file_pos = name.find_last_of('\\');
2178
2179 // Debug only
2180 //printf("%40s, %i, %i, %i;\n", name src_pos, dir_pos, file_pos);
2181 // If dir_pos == file_pos, then we have ../src/filename.cxx
2182 // If dir_pos > file_pos, then we have ../filename.cxx or something odd.
2183
2184 // Step 2: see if it is or is not a ../src/ directory.
2185 if ((dir_pos < file_pos) && (dir_pos > src_pos))
2186 {
2187 new_dir = name.substr (dir_pos, file_pos-dir_pos);
2188 new_dir.replace( "..\\", ""); // All names are relative to package/Visual,
2189 // so we want to ditch the prevailing ..\ ;
2190 // which all of them have.
2191 }
2192 else
2193 {
2194 new_dir = "Source Files NN";
2195 }
2196
2197 // Step 3: Add directory structure to vcproj file.
2198 if (new_dir != directory) // Detects a change in directory
2199 {
2200 directory = new_dir;
2201 // Step 3a: Add a </Filter> when neccessary.
2202 if (need_trailer == false)
2203 {
2204 // Ensure that no trailing </Filter> is placed incorrectly.
2205 need_trailer = true;
2206 }
2207 else
2208 {
2209 vcproj_directory_trailer_fragment.wincopy (m_output_file,
2210 constituent.variables, 1,
2211 &m_PACKAGE);
2212 }
2213
2214 // Step 3b: Add a <Filter> when neccessary.
2215 if ((dir_pos < file_pos) && (dir_pos > src_pos))
2216 {
2217 // Add <Filter Name="directory">
2218 m_DIRNAME = new_dir;
2219 vcproj_directory_header_fragment.wincopy (m_output_file, constituent.variables, 2,
2220 &m_PACKAGE,
2221 &m_DIRNAME);
2222 }
2223 else
2224 {
2225 // Ensure that no </Filter> is placed incorrectly.
2226 // This is the case of the file being in ../src
2227 // which requires no directory. Thus no filter start or end tag is needed.
2228
2229 need_trailer = false;
2230 }
2231 }
2232
2233 if (m_output_file != NULL)
2234 {
2235 vcproj_contents_fragment.wincopy (m_output_file, constituent.variables, 2,
2236 &m_PACKAGE,
2237 &m_FULLNAME);
2238 }
2239 }
2240 }
2241 }
2242
2243 if (need_trailer == true)
2244 {
2245 // Add a trailing </Filter> for directory support.
2246 vcproj_directory_trailer_fragment.wincopy (m_output_file, constituent.variables, 1,
2247 &m_PACKAGE);
2248 }
2249
2250 if (m_output_file != NULL)
2251 {
2252 vcproj_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
2253 &m_PACKAGE,
2254 &m_CONSTITUENT,
2255 &m_CONSTITUENTSUFFIX);
2256
2257 terminate ();
2258 }
2259
2260 return (0);
2261}
2262
2263MakeSetupGenerator::MakeSetupGenerator ()
2264{
2265 make_setup_header_fragment.set ("make_setup_header");
2266 make_setup_fragment.set ("make_setup");
2267}
2268
2269void MakeSetupGenerator::reset ()
2270{
2271 CmtGenerator::reset ();
2272
2273 make_setup_header_fragment.reset ();
2274 make_setup_fragment.reset ();
2275}
2276
2277void MakeSetupGenerator::build (const cmt_string& package)
2278{
2279 reset ();
2280
2281 m_PACKAGE = package;
2282
2283 cmt_string file_name = "setup.";
2284
2285 if (Cmt::build_nmake ())
2286 {
2287 file_name += "nmake";
2288 }
2289 else
2290 {
2291 file_name += "make";
2292 }
2293
2294 cmt_string new_file_name = file_name;
2295 new_file_name += "new";
2296
2297 m_output_file = fopen (new_file_name, "wb");
2298
2299 if (m_output_file != NULL)
2300 {
2301 int number;
2302
2303 const Use::UsePtrVector& uses = Use::get_ordered_uses ();
2304
2305 const Constituent::ConstituentVector& constituents =
2306 Constituent::constituents ();
2307
2308 cmt_string temp;
2309
2310 make_setup_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2311
2312 for (number = 0; number < uses.size (); number++)
2313 {
2314 const Use* use = uses[number];
2315
2316 if (use->discarded) continue;
2317
2318 if (use->real_path != "")
2319 {
2320 temp = use->prefix;
2321 temp += "ROOT = ";
2322 temp += use->get_full_path ();
2323
2324 fprintf (m_output_file, "%s\n", temp.c_str());
2325 }
2326 }
2327
2328 temp = "use_requirements = ";
2329 temp += "requirements ";
2330
2331 for (number = 0; number < uses.size (); number++)
2332 {
2333 const Use* use = uses[number];
2334
2335 if (use->discarded) continue;
2336
2337 if (use->real_path != "")
2338 {
2339 temp += "$(";
2340 temp += use->prefix;
2341 temp += "ROOT)";
2342 temp += CmtSystem::file_separator ();
2343 switch (use->style)
2344 {
2345 case cmt_style:
2346 temp += "cmt";
2347 break;
2348 case mgr_style:
2349 temp += "mgr";
2350 break;
2351 }
2352 temp += CmtSystem::file_separator ();
2353 temp += "requirements ";
2354 }
2355 }
2356
2357 fprintf (m_output_file, "%s\n", temp.c_str());
2358
2359 temp = "constituents = $(constituents)";
2360 Symbol::expand (temp);
2361
2362 fprintf (m_output_file, "%s\n", temp.c_str());
2363
2364 make_setup_fragment.copy (m_output_file, 1, &m_PACKAGE);
2365
2366 fclose (m_output_file);
2367
2368 //--- Complete the operation --------------
2369
2370 commit (new_file_name);
2371 }
2372
2373 /*
2374 for option in $*
2375 do
2376 case ${option} in
2377 args-tag=*)
2378 tag=${option}
2379 tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2380 ;;
2381 -tag=*)
2382 tag=args${option}
2383 tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2384 ;;
2385 esac
2386 done
2387
2388 if test "${tag}" = "" ; then
2389 tag=${CMTCONFIG}
2390 fi
2391
2392 build_shell_setup_files ${tag}
2393
2394 now=`date`
2395
2396 */
2397}
2398
2399ConstituentsMakefileGenerator::ConstituentsMakefileGenerator ()
2400{
2401 constituents_header_fragment.set ("constituents_header");
2402 constituents_trailer_fragment.set ("constituents_trailer");
2403 group_fragment.set ("group");
2404 constituent_fragment.set ("constituent");
2405 check_application_header_fragment.set ("check_application_header");
2406}
2407
2408void ConstituentsMakefileGenerator::reset ()
2409{
2410 CmtGenerator::reset ();
2411 constituents_header_fragment.reset ();
2412 constituents_trailer_fragment.reset ();
2413 group_fragment.reset ();
2414 constituent_fragment.reset ();
2415 check_application_header_fragment.reset ();
2416}
2417
2418//--------------------------------------------------
2419void ConstituentsMakefileGenerator::build (const cmt_string& package,
2420 const CmtSystem::cmt_string_vector& arguments)
2421{
2422 reset ();
2423
2424 cmt_string file_name;
2425
2426 if (arguments.size () > 0)
2427 {
2428 cmt_string arg = arguments[0];
2429 if (arg.substr (0, 5) == "-out=")
2430 {
2431 arg.erase (0, 5);
2432 file_name = arg;
2433 }
2434 }
2435
2436 if (file_name == "")
2437 {
2438 file_name = "constituents.";
2439
2440 //--- Build the constituents fragment -----
2441
2442 if (Cmt::build_nmake ())
2443 {
2444 file_name += "nmake";
2445 }
2446 else
2447 {
2448 file_name += "make";
2449 }
2450 }
2451
2452 cmt_string save_file_name = file_name;
2453 save_file_name += "sav";
2454
2455 if (CmtSystem::test_file (file_name))
2456 {
2457 rename (file_name, save_file_name);
2458 }
2459
2460 cmt_string new_file_name = file_name;
2461 new_file_name += "new";
2462
2463 m_output_file = fopen (new_file_name, "wb");
2464 if (m_output_file != NULL)
2465 {
2466 int number;
2467 const Constituent::ConstituentVector&
2468 constituents = Constituent::constituents ();
2469
2470 m_PACKAGE = package;
2471
2472 constituents_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2473
2474 m_GROUP = "all";
2475 group_fragment.copy (m_output_file, 1, &m_GROUP);
2476
2477 const Group::GroupVector& groups = Group::groups ();
2478
2479 for (number = 0; number < groups.size (); number++)
2480 {
2481 const Group& group = groups[number];
2482
2483 m_GROUP = group.name ();
2484
2485 group_fragment.copy (m_output_file, 1, &m_GROUP);
2486 }
2487
2488 for (number = 0; number < constituents.size (); number++)
2489 {
2490 const Constituent& constituent = constituents[number];
2491
2492 m_CONSTITUENT = constituent.name;
2493 m_CONSTITUENTSUFFIX = constituent.suffix;
2494
2495 m_LINE = "";
2496
2497 if (constituent.has_target_tag)
2498 {
2499 m_HASTARGETTAG = "has_target_tag";
2500 }
2501 else
2502 {
2503 m_HASTARGETTAG = "has_no_target_tag";
2504 }
2505
2506 constituent_fragment.copy (m_output_file, constituent.variables, 5,
2507 &m_PACKAGE,
2508 &m_CONSTITUENT,
2509 &m_CONSTITUENTSUFFIX,
2510 &m_LINE,
2511 &m_HASTARGETTAG);
2512
2513 if (constituent.need_check)
2514 {
2515 check_application_header_fragment.copy (m_output_file,
2516 constituent.variables, 3,
2517 &m_PACKAGE,
2518 &m_CONSTITUENT,
2519 &m_CONSTITUENTSUFFIX);
2520 }
2521 }
2522
2523 constituents_trailer_fragment.copy (m_output_file, 0);
2524
2525 fclose (m_output_file);
2526
2527 commit (new_file_name);
2528 }
2529}
2530
2531
2532
2533
2534/**
2535 With this Awk filter, we analyze an existing dependency file.
2536 We get the source name in each line
2537 The list of sources is maintained in m_sources
2538 A source is stored in the form <name>_<suffix> (instead of <name>.<suffix>)
2539*/
2540class DependencyFilter : public Awk
2541{
2542public:
2543 DependencyFilter ()
2544 {
2545 }
2546
2547 void begin ()
2548 {
2549 m_sources = "";
2550 }
2551
2552 void filter (const cmt_string& line)
2553 {
2554 int pos = line.find ("_dependencies = ");
2555 if (pos == cmt_string::npos) return;
2556
2557 cmt_string s = line;
2558 s.erase (pos);
2559
2560 m_sources += " ";
2561 m_sources += s;
2562 m_sources += " ";
2563
2564 //pos = s.find_last_of ("_");
2565 //if (pos != cmt_string::npos) s[pos] = "."
2566 }
2567
2568 void add_source (const cmt_string& file_name)
2569 {
2570 static cmt_string suffix;
2571 static cmt_string name;
2572
2573 CmtSystem::get_dot_suffix (file_name, suffix);
2574 CmtSystem::basename (file_name, suffix, name);
2575 CmtSystem::get_suffix (file_name, suffix);
2576
2577 cmt_string s = " ";
2578 s += name;
2579 s += "_";
2580 s += suffix;
2581 s += " ";
2582
2583 if (m_sources.find (s) == cmt_string::npos)
2584 {
2585 m_sources += s;
2586 }
2587 }
2588
2589 bool has_source (const cmt_string& file_name) const
2590 {
2591 static cmt_string suffix;
2592 static cmt_string name;
2593
2594 CmtSystem::get_dot_suffix (file_name, suffix);
2595 CmtSystem::basename (file_name, suffix, name);
2596 CmtSystem::get_suffix (file_name, suffix);
2597
2598 cmt_string s = " ";
2599 s += name;
2600 s += "_";
2601 s += suffix;
2602 s += " ";
2603
2604 if (m_sources.find (s) == cmt_string::npos)
2605 {
2606 return (false);
2607 }
2608 else
2609 {
2610 return (true);
2611 }
2612 }
2613
2614 cmt_string& get_sources ()
2615 {
2616 return (m_sources);
2617 }
2618
2619private:
2620 cmt_string m_sources;
2621};
2622
2623
2624void DependencyGenerator::build (const CmtSystem::cmt_string_vector& arguments)
2625{
2626 reset ();
2627 prepare_use_context ();
2628
2629 m_stamps = true;
2630
2631 const cmt_string& name = arguments[0];
2632
2633 //cerr << "name=" << name << endl;
2634
2635 m_constituent = Constituent::find (name);
2636 if (m_constituent == 0)
2637 {
2638 // Error : wrong constituent name...
2639
2640 return;
2641 }
2642
2643 const Constituent& constituent = *m_constituent;
2644
2645 cmt_string file_name;
2646 cmt_string full_name;
2647 cmt_string compressed_name;
2648 cmt_string suffix;
2649 cmt_string dependencies;
2650
2651 //
2652 // Now prepare the output file names
2653 //
2654 cmt_string branch = CmtSystem::current_branch ();
2655
2656 if ((branch == "mgr") || (branch == "cmt"))
2657 {
2658 Use& current_use = Use::current ();
2659
2660 Package* p = current_use.get_package ();
2661
2662 if (p->is_cmt ())
2663 {
2664 m_bin = "../";
2665 m_bin += CmtSystem::getenv ("CMTBIN");
2666 m_bin += CmtSystem::file_separator ();
2667 }
2668 else
2669 {
2670 m_bin = "${bin}";
2671 }
2672
2673 Symbol::expand (m_bin);
2674
2675 //cerr << "m_output_file_name=" << m_output_file_name << endl;
2676 //cerr << "current_tag=" << Cmt::current_tag << endl;
2677 }
2678 else
2679 {
2680 m_bin = ".";
2681 m_bin += CmtSystem::file_separator ();
2682 }
2683
2684 m_output_file_name = m_bin;
2685 m_output_file_name += name;
2686 m_output_file_name += "_";
2687 m_output_file_name += "dependencies.";
2688 if (Cmt::build_nmake ())
2689 {
2690 m_output_file_name += "nmake";
2691 }
2692 else
2693 {
2694 m_output_file_name += "make";
2695 }
2696
2697 //
2698 // New read the existing dependency file if any and filter it to
2699 // extract the source names
2700 //
2701 static DependencyFilter filter;
2702
2703 dependencies.read (m_output_file_name);
2704
2705 filter.run (dependencies);
2706
2707 //
2708 // Scan the sources.
2709 //
2710
2711 //
2712 // We have to rebuild the dependencies for :
2713 //
2714 // o all sources if the parameter -all_sources has been received
2715 // o otherwise,
2716 // + all source names provided in the argument list (if any)
2717 // + all source names missing from the existing dependency file (if any)
2718 //
2719
2720 const CmtSystem::cmt_string_vector& sources = constituent.modules;
2721 const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
2722 const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
2723
2724 bool all_sources = false;
2725
2726 int source_number = arguments.size ();
2727 int i;
2728
2729 //cerr << "source_number=" << source_number << endl;
2730
2731 for (i = source_number-1; i >= 0; i--)
2732 {
2733 file_name = arguments[i];
2734
2735 //cerr << "file_name=" << file_name << endl;
2736
2737 // Get rid of files that may come from the makefile fragment
2738 if (file_name.find ("requirements") != cmt_string::npos) source_number--;
2739 else if (file_name.find (".make") != cmt_string::npos) source_number--;
2740 else if (file_name == "-all_sources")
2741 {
2742 source_number = sources.size ();
2743 all_sources = true;
2744 }
2745 else if (file_name == "-no_stamps")
2746 {
2747 source_number--;
2748 m_stamps = false;
2749 }
2750 }
2751
2752
2753 if (all_sources)
2754 {
2755 for (i = 0; i < sources.size (); i++)
2756 {
2757 file_name = sources[i];
2758
2759 set_full_name (full_name, file_name);
2760 if (full_name == "") continue;
2761
2762 CmtSystem::compress_path (full_name, compressed_name);
2763 full_name = compressed_name;
2764
2765 static CmtSystem::cmt_string_vector files;
2766
2767 get_all_files (full_name, excludes, selects, files);
2768
2769 for (int j = 0; j < files.size (); j++)
2770 {
2771 const cmt_string& name = files[j];
2772
2773 if (name != "")
2774 {
2775 const cmt_string& line = build (name);
2776
2777 //cout << ">>> line=[" << line << "]" << endl;
2778
2779 add_line_to_text (line, dependencies);
2780 }
2781 }
2782 }
2783 }
2784 else
2785 {
2786 for (i = 1; i < source_number; i++)
2787 {
2788 file_name = arguments[i];
2789
2790 set_full_name (full_name, file_name);
2791 if (full_name == "") continue;
2792
2793 CmtSystem::compress_path (full_name, compressed_name);
2794 full_name = compressed_name;
2795
2796 const cmt_string& line = build (full_name);
2797
2798 //cout << ">>> name2=" << full_name << endl;
2799
2800 add_line_to_text (line, dependencies);
2801
2802 //cout << ">>from deps : " << filter.get_sources () << endl;
2803 filter.add_source (full_name);
2804
2805 }
2806
2807 //cout << ">>from deps : " << filter.get_sources () << endl;
2808
2809 // Now : are there still any missing source file in dependencies??
2810
2811 for (i = 0; i < sources.size (); i++)
2812 {
2813 file_name = sources[i];
2814
2815 set_full_name (full_name, file_name);
2816 if (full_name == "") continue;
2817
2818 CmtSystem::compress_path (full_name, compressed_name);
2819 full_name = compressed_name;
2820
2821 static CmtSystem::cmt_string_vector files;
2822
2823 get_all_files (full_name, excludes, selects, files);
2824
2825 for (int j = 0; j < files.size (); j++)
2826 {
2827 const cmt_string& name = files[j];
2828 if (name != "")
2829 {
2830 if (!filter.has_source (name))
2831 {
2832 const cmt_string& line = build (name);
2833
2834 //cout << ">>> name3=" << name << endl;
2835
2836 add_line_to_text (line, dependencies);
2837 }
2838 }
2839 }
2840 }
2841 }
2842
2843 FILE* f = fopen (m_output_file_name.c_str (), "wb");
2844
2845 if (f == 0)
2846 {
2847 cerr << "Cannot open " << m_output_file_name << " for write" << endl;
2848 }
2849 else
2850 {
2851 dependencies.write (f);
2852 fclose (f);
2853 }
2854}
2855
2856//--------------------------------------------------
2857// o text contains lines with a pattern like :
2858// key = xxxxx
2859//
2860// o line follows the same pattern
2861//
2862// This function appends <line> to <text> only if the key found in
2863// <line> is not found in <text>
2864//--------------------------------------------------
2865void DependencyGenerator::add_line_to_text (const cmt_string& line, cmt_string& text)
2866{
2867 static const cmt_string empty;
2868
2869 int pos = line.find (" = ");
2870 if (pos != cmt_string::npos)
2871 {
2872 static cmt_string key;
2873 line.substr (0, pos + 3, key);
2874 pos = text.find (key);
2875 if (pos != cmt_string::npos)
2876 {
2877 // The key in line exists in text.
2878 // Now check if the key is exactly the same.
2879
2880 if ((pos == 0) || (text[pos -1] == '\n'))
2881 {
2882 // The key is either in the first line or
2883 // exactly matches '^key = ...'
2884
2885 int nl = text.find (pos, "\n");
2886 if (nl != cmt_string::npos)
2887 {
2888 static cmt_string old;
2889 text.substr (pos, nl - pos + 1, old);
2890 text.replace (old, empty);
2891 }
2892 else
2893 {
2894 text.erase (pos);
2895 }
2896 }
2897 }
2898 }
2899 if (line != "")
2900 {
2901 text += line;
2902 text += "\n";
2903 }
2904}
2905
2906cmt_string DependencyGenerator::build (const cmt_string& file_name)
2907{
2908 Log;
2909
2910 const Constituent& constituent = *m_constituent;
2911
2912 static cmt_string full_name;
2913 static cmt_string suffix;
2914 static cmt_string name;
2915 static cmt_string line;
2916
2917 full_name = "";
2918 line = "";
2919
2920 if (!CmtSystem::absolute_path (file_name))
2921 {
2922 full_name = srcdir;
2923 }
2924
2925 full_name += file_name;
2926
2927 CmtSystem::get_dot_suffix (full_name, suffix);
2928 CmtSystem::basename (full_name, suffix, name);
2929 CmtSystem::get_suffix (full_name, suffix);
2930
2931 if (name == "requirements") return (line);
2932
2933 const CmtSystem::cmt_string_vector& deps = m_deps_builder.run (full_name);
2934
2935 line = name;
2936 line += "_";
2937 line += suffix;
2938 line += "_dependencies = ";
2939
2940 filter_path (full_name);
2941
2942#ifdef WIN32
2943 static const char quote = '\"';
2944#else
2945 static const char quote = ' ';
2946#endif
2947
2948 line += quote;
2949 line += full_name;
2950 line += quote;
2951
2952 for (int j = 0; j < deps.size (); j++)
2953 {
2954 cmt_string d = deps[j];
2955
2956 log << "dep line = " << d << log_endl;
2957
2958 filter_path (d);
2959
2960 log << "filtered dep line = " << d << log_endl;
2961
2962 line += " ";
2963 line += quote;
2964 line += d;
2965 line += quote;
2966 }
2967
2968 Symbol::expand (line);
2969
2970 if (m_stamps)
2971 {
2972 cmt_string stamp_output_base = constituent.name;
2973 stamp_output_base += "_deps";
2974
2975 cmt_string stamp_output = m_bin;
2976 stamp_output += stamp_output_base;
2977
2978 if (!CmtSystem::mkdir (stamp_output))
2979 {
2980 cerr << "Cannot create the binary output directory for this constituent" << endl;
2981 }
2982
2983 stamp_output_base += CmtSystem::file_separator ();
2984 stamp_output_base += name;
2985 stamp_output_base += "_";
2986 stamp_output_base += suffix;
2987 stamp_output_base += ".stamp";
2988
2989 stamp_output = m_bin;
2990 stamp_output += stamp_output_base;
2991
2992 line += " $(bin)";
2993 line += stamp_output_base;
2994
2995 cmt_string old_stamp;
2996
2997 if (CmtSystem::test_file (stamp_output))
2998 {
2999 old_stamp.read (stamp_output);
3000 }
3001
3002 if (line != old_stamp)
3003 {
3004 line.write (stamp_output);
3005 }
3006 }
3007
3008 return (line);
3009}
3010
Note: See TracBrowser for help on using the repository browser.