source: CMT/v1r20p20090520/source/cmt_generators.cxx

Last change on this file was 488, checked in by rybkin, 15 years ago

See C.L. 383

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