source: CMT/v1r20p20070720/source/cmt_generators.cxx

Last change on this file was 400, checked in by arnault, 17 years ago

Text formatting
Sending warnings & errors to stderr
Using internally PWD for every cd/pwd
CL 327

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