source: CMT/v1r16p20040901/src/cmt_generators.cxx @ 1

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

Import all tags

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