source: CMT/v1r25-branch/source/cmt_generators.cxx @ 664

Last change on this file since 664 was 664, checked in by rybkin, 10 years ago

merge -r 646:663 HEAD

  • Property svn:eol-style set to native
File size: 103.3 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by Grigory Rybkin
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#include "cmt_generators.h"
9#include "cmt_awk.h"
10#include "cmt_use.h"
11#include "cmt_symbol.h"
12#include "cmt_log.h"
13#include "cmt_error.h"
14#include <assert.h>
15#include "cmt_project.h"
16
17//--------------------------------------------------
18AnyDocumentGenerator::AnyDocumentGenerator ()
19{
20  m_TITLE.set ("TITLE");
21  m_STRUCTURED_OUTPUT.set ("STRUCTURED_OUTPUT");
22
23  make_header_fragment.set ("make_header");
24  cleanup_header_fragment.set ("cleanup_header");
25  cleanup_fragment.set ("cleanup");
26  dependencies_fragment.set ("dependencies");
27  dependencies_and_triggers_fragment.set ("dependencies_and_triggers");
28}
29
30void AnyDocumentGenerator::reset ()
31{
32  CmtGenerator::reset ();
33  m_TITLE = "";
34
35  make_header_fragment.reset ();
36  cleanup_header_fragment.reset ();
37  cleanup_fragment.reset ();
38  dependencies_fragment.reset ();
39  dependencies_and_triggers_fragment.reset ();
40}
41
42//--------------------------------------------------
43LibraryGenerator::LibraryGenerator ()
44{
45  library_header_fragment.set ("library_header");
46  application_header_fragment.set ("application_header");
47  java_header_fragment.set ("java_header");
48  jar_header_fragment.set ("jar_header");
49  protos_header_fragment.set ("protos_header");
50  library_fragment.set ("library");
51  library_no_share_fragment.set ("library_no_share");
52  library_no_static_fragment.set ("library_no_static");
53  application_fragment.set ("application");
54  jar_fragment.set ("jar");
55  java_fragment.set ("java");
56  java_copy_fragment.set ("java_copy");
57  cleanup_library_fragment.set ("cleanup_library");
58  cleanup_application_fragment.set ("cleanup_application");
59  cleanup_java_fragment.set ("cleanup_java");
60  cleanup_objects_fragment.set ("cleanup_objects");
61  buildproto_fragment.set ("buildproto");
62  check_application_fragment.set ("check_application");
63  check_java_fragment.set ("check_java");
64}
65
66//--------------------------------------------------
67void LibraryGenerator::reset ()
68{
69  AnyDocumentGenerator::reset ();
70  library_header_fragment.reset ();
71  application_header_fragment.reset ();
72  java_header_fragment.reset ();
73  jar_header_fragment.reset ();
74  protos_header_fragment.reset ();
75  library_fragment.reset ();
76  library_no_share_fragment.reset ();
77  library_no_static_fragment.reset ();
78  jar_fragment.reset ();
79  application_fragment.reset ();
80  java_fragment.reset ();
81  java_copy_fragment.reset ();
82  cleanup_library_fragment.reset ();
83  cleanup_application_fragment.reset ();
84  cleanup_java_fragment.reset ();
85  cleanup_objects_fragment.reset ();
86  buildproto_fragment.reset ();
87  check_application_fragment.reset ();
88  check_java_fragment.reset ();
89}
90
91//--------------------------------------------------
92bool LibraryGenerator::analyze_file (const Constituent& constituent,
93                                     const cmt_string& file)
94{
95  static cmt_string suffix;
96  static cmt_string name;
97  static cmt_string obj;
98
99  bool file_not_found = false;
100  bool can_build = true;
101
102  obj = file;
103
104  if (Cmt::get_debug ())
105    {
106      cout << "CmtGenerator::analyze_file> constituent=" << 
107        constituent.name <<
108        " file=" << file << endl;
109    }
110
111  if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file))
112    {
113      file_not_found = true;
114      CmtMessage::warning ("Source file " + file + " not found");
115      //      cerr << "#CMT> Warning: Source file " << file << " not found" << endl;
116    }
117
118  CmtSystem::get_suffix (file, suffix);
119  CmtSystem::basename (file, suffix, name);
120
121  Language& language = Language::find_with_suffix (suffix);
122
123  if (m_LINKMACRO == "")
124    {
125      m_LINKMACRO = language.linker;
126    }
127
128  if (language == "java")
129    {
130      static Packager packager;
131     
132      obj  = "$(javabin)";
133      obj +=  m_CONSTITUENT;
134      obj +=  CmtSystem::file_separator ();
135
136      cmt_regexp exp ("^package[ \t][ \t]*[a-zA-Z0-9_.][a-zA-Z0-9_.][ \t]*;");
137     
138      packager.run (file, exp);
139      if (packager.package_name () != "")
140        {
141          obj += packager.package_name ();
142          obj += CmtSystem::file_separator ();
143        }
144     
145      obj += name;
146      obj += ".class";
147    }
148  else if (language != Language::null ())
149    {
150      obj  = "$(bin)";     
151
152      if (CmtSystem::getenv("STRUCTURED_OUTPUT")!="" || Cmt::build_nmake ())
153        {
154          obj +=  m_CONSTITUENT;
155          obj +=  CmtSystem::file_separator ();
156        }
157
158      obj += name;
159      obj += language.output_suffix;
160      obj += constituent.suffix;
161      if (Cmt::build_nmake ()) obj += ".obj";
162      else obj += ".o";
163 
164      for (int i = 0; i < language.extra_output_suffixes.size (); i++)
165        {
166          cmt_string& extra_suffix = language.extra_output_suffixes[i];
167
168          obj += " $(bin)";
169          obj += name;
170          obj += extra_suffix;
171          obj += language.output_suffix;
172          obj += constituent.suffix;
173          if (Cmt::build_nmake ()) obj += ".obj";
174          else obj += ".o";
175        }
176    }
177  else
178    {
179      if (m_LINKMACRO == "java")
180        {
181          obj  = "$(javabin)";
182          obj +=  m_CONSTITUENT;
183          obj +=  CmtSystem::file_separator ();
184          obj += file;
185         
186          obj.replace ("../src/", "");
187          obj.replace ("..\\src\\", "");
188        }
189      else if (file_not_found)
190        {
191          can_build = false;
192          obj  = "";
193          CmtMessage::warning ("Source file " + name + " cannot be rebuilt");
194          //      cerr << "#CMT> Warning: Source file " << name << " cannot be rebuilt" << endl;
195        }
196      else
197        {
198          obj  = "";
199        }
200    }
201
202  if (Cmt::get_debug ())
203    {
204      cout << "LibraryGenerator::analyze_file> constituent=" << 
205        constituent.name <<
206        " obj=" << obj << endl;
207    }
208
209  if (can_build)
210    {
211      SourceFile& source = m_source_files.add ();
212      source.set (file, language, obj);
213      return (true);
214    }
215  else
216    {
217      return (false);
218    }
219}
220
221//--------------------------------------------------
222void LibraryGenerator::java_file_action (SourceFile& file, const Constituent& constituent)
223{
224  static cmt_string suffix;
225
226  m_FULLNAME = file.name ();
227  m_OUTPUTNAME = file.output ();
228
229  CmtSystem::get_dot_suffix (m_FULLNAME, suffix);
230 
231  CmtSystem::basename (m_FULLNAME, suffix, m_NAME.value);
232  CmtSystem::basename (m_FULLNAME, m_FILENAME.value);
233 
234  //  if (CmtSystem::test_file (m_FULLNAME))
235  //    {
236      java_fragment.copy (m_output_file, constituent.variables, 5,
237                          &m_NAME,
238                          &m_FULLNAME,
239                          &m_OUTPUTNAME,
240                          &m_CONSTITUENT, 
241                          &m_CONSTITUENTSUFFIX);
242      /*
243    }
244  else
245    {
246      CmtMessage::warning ("file " + m_FULLNAME + " not found");
247      //      cerr << "#CMT> Warning: file " << m_FULLNAME << " not found" << endl;
248    }
249      */
250}
251
252//--------------------------------------------------
253void LibraryGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent)
254{
255  static cmt_string suffix;
256
257  CmtSystem::dirname (file, m_FILEPATH.value);
258  if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
259
260  filter_path (m_FILEPATH.value);
261
262  CmtSystem::basename (file, m_FILENAME.value);
263  CmtSystem::get_dot_suffix (m_FILENAME, suffix);
264
265  CmtSystem::basename (m_FILENAME, suffix, m_NAME.value);
266
267  buildproto_fragment.copy (m_output_file, constituent.variables, 4,
268                            &m_CONSTITUENT,
269                            &m_NAME, 
270                            &m_FILEPATH, 
271                            &m_FILENAME);
272}
273
274//--------------------------------------------------
275void LibraryGenerator::prepare_proto_file (const cmt_string& file)
276{
277  static cmt_string name;
278  static cmt_string pp;
279
280  CmtSystem::name (file, name);
281
282  if (CmtSystem::test_file (file))
283    {
284      pp  = incdir;
285      pp += name;
286      pp += ".pp";
287
288      if (!CmtSystem::test_file (pp))
289        {
290          //Generator::build_prototype (file);
291        }
292    }
293
294  protos += " ";
295  protos += inc;
296  protos += name;
297  protos += ".ph";
298
299  protonames += " ";
300  protonames += name;
301  protonames += ".ph";
302
303  m_PROTOSTAMPS += " ";
304  m_PROTOSTAMPS += inc;
305  m_PROTOSTAMPS += name;
306  m_PROTOSTAMPS += ".pp";
307}
308
309//--------------------------------------------------
310void LibraryGenerator::module_file_action (SourceFile& file, const Constituent& constituent)
311{
312  cmt_string name = file.name ();
313  Language& language = file.language ();
314
315  static cmt_string suffix;
316  static cmt_string prefix;
317  static cmt_string preproc;
318
319  m_FULLNAME = name;
320
321  CmtSystem::get_dot_suffix (name, suffix);
322
323  CmtSystem::basename (name, suffix, m_NAME.value);
324
325  CmtSystem::dirname (name, prefix);
326  CmtSystem::basename (name, m_FILENAME.value);
327
328  FragmentHandle* fragment;
329
330  if (language != Language::null ())
331    {
332      preproc = language.preprocessor_command;
333      fragment = (is_library) ? &(language.library) : &(language.application);
334      m_DEPENDENCIESOPTS = language.dependencies_options ();
335    }
336  else
337    {
338      //
339      // What happens when the language is not known???
340      //
341      //
342      preproc = "-I";
343      fragment = 0;
344    }
345
346  if ((prefix == "../src") || (prefix == "..\\src"))
347    {
348      m_ADDINCLUDE = "";
349    }
350  else if (prefix != "")
351    {
352      m_ADDINCLUDE  = preproc;
353      m_ADDINCLUDE += prefix;
354    }
355
356  m_FILEPATH = prefix;
357  if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
358  filter_path (m_FILEPATH.value);
359
360  /*
361  m_LINE = m_FULLNAME.value;
362  m_LINE += " ";
363  */
364
365  filter_path (m_FULLNAME.value);
366
367  CmtSystem::get_suffix (name, m_FILESUFFIX.value);
368
369  if (fragment != 0)
370    {
371      //      fragment->copy (m_output_file, constituent.variables, 10,
372      fragment->copy (m_output_file, constituent.variables, 11,
373                      &m_CONSTITUENT, 
374                      &m_CONSTITUENTSUFFIX, 
375                      &m_FILENAME, 
376                      &m_NAME, 
377                      &m_LINE,
378                      &m_ADDINCLUDE, 
379                      &m_FULLNAME, 
380                      &m_FILEPATH, 
381                      &m_FILESUFFIX, 
382                      &m_PACKAGE,
383                      &m_DEPENDENCIESOPTS);
384    }
385  else if (file.output () != "")
386    {
387      m_OUTPUTNAME = file.output ();
388      CmtSystem::dirname (m_OUTPUTNAME.value, m_FILEPATH.value);
389
390      java_copy_fragment.copy (m_output_file, constituent.variables, 11,
391                               &m_CONSTITUENT, 
392                               &m_CONSTITUENTSUFFIX, 
393                               &m_FILENAME, 
394                               &m_NAME, 
395                               &m_LINE,
396                               &m_ADDINCLUDE, 
397                               &m_FULLNAME, 
398                               &m_FILEPATH, 
399                               &m_FILESUFFIX, 
400                               &m_PACKAGE, 
401                               &m_OUTPUTNAME);
402    }
403
404  if (m_PACKOS9)
405    {
406      //      os9sources += m_LINE;
407      os9sources += m_FULLNAME.value;
408      os9sources += " ";
409    }
410}
411
412//--------------------------------------------------
413void LibraryGenerator::fill_names_outputs ()
414{
415  bool l_first = true;
416  bool o_first = true;
417
418  m_LINE = "";
419  m_OBJS = "";
420
421  for (int i = 0; i < m_source_files.size (); i++)
422    {
423      const SourceFile& file = m_source_files[i];
424      const cmt_string name = file.name ();
425      const cmt_string output = file.output ();
426      Language& language = file.language ();
427
428      if (output != "")
429        {
430          if (o_first)
431            {
432              o_first = false;
433            }
434          else
435            {
436              m_OBJS += " ";
437            }
438          m_OBJS += output;
439
440          if (language == Language::null () || !language.native_dependencies ())
441            {
442              if (l_first)
443                {
444                  l_first = false;
445                }
446              else
447                {
448                  m_LINE += " ";
449                }
450              m_LINE += name;
451            }
452        }
453
454      if (Cmt::get_debug ())
455        {
456          cout << "LibraryGenerator::fill_names_outputs>" << endl;
457          cout << "name=" << name << " LINE=" << m_LINE << endl;
458          cout << "output=" << output << " OBJS=" << m_OBJS << endl;
459        }
460    }
461
462  filter_path (m_LINE.value);
463}
464
465//--------------------------------------------------
466void LibraryGenerator::build (const cmt_string& package,
467                              const Constituent& constituent,
468                              bool& dependencies,
469                              const cmt_string& file_name)
470{
471  static cmt_string lib;
472  static cmt_string allsources;
473  static cmt_string file;
474  static cmt_string full_name;
475  static cmt_string compressed_name;
476  static cmt_string suffix;
477  int i;
478  bool need_prototypes;
479
480  reset ();
481
482  if (!prepare_output (package, constituent, file_name)) return;
483
484  switch (constituent.type)
485    {
486    case Application:
487      is_library = false;
488      is_application = true;
489      m_TITLE = "Application";
490      break;
491    case Library:
492      is_library = true;
493      is_application = false;
494      m_TITLE = "Library";
495      break;
496    }
497
498  m_source_files.clear ();
499
500  need_prototypes = constituent.need_prototypes;
501
502  //  cout << m_TITLE << " " << m_CONSTITUENT << endl;
503  CmtMessage::info (m_TITLE + " " + m_CONSTITUENT);
504
505  lib  = "$(";
506  lib += m_CONSTITUENT;
507  lib += "lib)";
508
509  //
510  // Prepare the include paths
511  //
512
513  const CmtSystem::cmt_string_vector& includes = constituent.includes;
514
515  for (i = 0; i < includes.size (); i++)
516    {
517      const cmt_string& subdir = includes[i];
518
519      m_PACKINCLUDES += " -I";
520      m_PACKINCLUDES += subdir;
521    }
522
523  //
524  // Scan the sources.
525  //
526
527  const CmtSystem::cmt_string_vector& sources = constituent.modules;
528  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
529  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
530
531  //  m_LINE = "";
532
533  for (i = 0; i < sources.size (); i++)
534    {
535      file = sources[i];
536
537      set_full_name (full_name, file);
538      if (full_name == "") continue;
539
540      CmtSystem::compress_path (full_name, compressed_name);
541      full_name = compressed_name;
542
543      static CmtSystem::cmt_string_vector files;
544
545      int count = get_all_files (full_name, excludes, selects, files);
546
547      filter_path (full_name);
548
549      for (int j = 0; j < files.size (); j++)
550        {
551          const cmt_string& name = files[j];
552
553          if (name != "") 
554            {
555              if (!analyze_file (constituent, name)) 
556                {
557                  count = 0;
558                  break;
559                }
560            }
561        }
562
563      /*
564      if (count > 0)
565        {
566          m_LINE += full_name;
567          m_LINE += " ";
568        }
569      */
570    }
571
572  fill_names_outputs ();
573  //fill_outputs ();
574
575  //prepare_use_context ();
576
577  m_DATE = CmtSystem::now ();
578  m_USER = CmtSystem::user ();
579  m_PACKAGE = package;
580
581  if (constituent.has_target_tag)
582    {
583      m_HASTARGETTAG = "has_target_tag";
584    }
585  else
586    {
587      m_HASTARGETTAG = "has_no_target_tag";
588    }
589   
590  m_HASDEPENDENCIES = "has_dependencies";
591
592  m_STRUCTURED_OUTPUT = "STRUCTURED_OUTPUT";
593
594  make_header_fragment.copy (m_output_file, constituent.variables, 9, 
595                             &m_TITLE,
596                             &m_CONSTITUENT,
597                             &m_CONSTITUENTSUFFIX,
598                             &m_USER,
599                             &m_DATE,
600                             &m_PACKAGE,
601                             &m_HASTARGETTAG,
602                             &m_HASDEPENDENCIES,
603                             &m_STRUCTURED_OUTPUT
604                             );
605
606  if (need_prototypes)
607    {
608      need_prototypes = false;
609
610      for (i = 0; i < m_source_files.size (); i++)
611        {
612          const SourceFile& file = m_source_files[i];
613          Language& language = file.language ();
614          if (language.prototypes)
615            {
616              need_prototypes = true;
617              break;
618            }
619        }
620    }
621
622  //-------------------------------------------
623  //
624  // Specific targets (application, library or java)
625  // Prepare in case prototype files are needed
626  //
627  //-------------------------------------------
628
629  m_PROTOTARGET = "";
630
631  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
632  if (need_prototypes)
633    {
634      m_PROTOTARGET = m_CONSTITUENT;
635      m_PROTOTARGET += "PROTOS";
636    }
637
638  if (m_LINKMACRO == "java")
639    {
640      if (is_library)
641        {
642          jar_header_fragment.copy (m_output_file, constituent.variables, 3, 
643                                    &m_CONSTITUENT, 
644                                    &m_CONSTITUENTSUFFIX,
645                                    &m_OBJS);
646        }
647      else
648        {
649          java_header_fragment.copy (m_output_file, constituent.variables, 3, 
650                                     &m_CONSTITUENT,
651                                     &m_CONSTITUENTSUFFIX,
652                                     &m_OBJS);
653        }
654    }
655  else
656    {
657      if (is_library)
658        {
659          library_header_fragment.copy (m_output_file, constituent.variables, 3,
660                                        &m_CONSTITUENT,
661                                        &m_CONSTITUENTSUFFIX,
662                                        &m_PROTOTARGET);
663        }
664      else
665        {
666          application_header_fragment.copy (m_output_file, constituent.variables, 3,
667                                            &m_CONSTITUENT, 
668                                            &m_CONSTITUENTSUFFIX, 
669                                            &m_PROTOTARGET);
670        }
671    }
672
673
674  //----------------------------------------------------
675  //
676  // Preparing prototype files.
677  //
678  //----------------------------------------------------
679
680  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
681  if (need_prototypes)
682    {
683      for (i = 0; i < m_source_files.size (); i++)
684        {
685          const SourceFile& file = m_source_files[i];
686          Language& language = file.language ();
687          if (language.prototypes)
688            {
689              prepare_proto_file (file.name ());
690            }
691        }
692
693      if (m_PROTOSTAMPS != "")
694        {
695          protos_header_fragment.copy (m_output_file, constituent.variables, 4,
696                                       &m_CONSTITUENT,
697                                       &m_CONSTITUENTSUFFIX,
698                                       &m_PROTOSTAMPS,
699                                       &m_OBJS);
700        }
701
702      if (protonames != "")
703        {
704          for (i = 0; i < m_source_files.size (); i++)
705            {
706              const SourceFile& file = m_source_files[i];
707              Language& language = file.language ();
708              if (language.prototypes)
709                {
710                  proto_file_action (file.name (), constituent);
711                }
712            }
713        }
714    }
715
716  //----------------------------------------------------
717  //
718  // Preparing the library.
719  //
720  //----------------------------------------------------
721
722  if (m_OBJS != "")
723    {
724      if (m_LINKMACRO == "java")
725        {
726          if (is_library)
727            {
728              cmt_string classes = m_OBJS.value;
729
730              classes.replace_all ("$(javabin)", "");
731              classes.replace_all (srcdir.c_str (), "");
732
733              m_CLASSES = classes;
734
735              jar_fragment.copy (m_output_file, constituent.variables, 4, 
736                                 &m_CONSTITUENT,
737                                 &m_CONSTITUENTSUFFIX,
738                                 &m_OBJS,
739                                 &m_CLASSES);
740            }
741        }
742      else
743        {
744          if (is_library)
745            {
746              if (constituent.no_share && constituent.no_static)
747                {
748                  CmtMessage::warning (constituent.name + ": No shared or static library");
749                }
750              else if (constituent.no_share)
751                {
752                  library_no_share_fragment.copy (m_output_file, constituent.variables, 3, 
753                                                  &m_CONSTITUENT,
754                                                  &m_CONSTITUENTSUFFIX,
755                                                  &m_OBJS);
756                }
757              else if (constituent.no_static)
758                {
759                  library_no_static_fragment.copy (m_output_file, constituent.variables, 3, 
760                                                  &m_CONSTITUENT,
761                                                  &m_CONSTITUENTSUFFIX,
762                                                  &m_OBJS);
763                }
764              else
765                {
766                  library_fragment.copy (m_output_file, constituent.variables, 3, 
767                                         &m_CONSTITUENT,
768                                         &m_CONSTITUENTSUFFIX,
769                                         &m_OBJS);
770                }
771            }
772          else
773            {
774              application_fragment.copy (m_output_file, constituent.variables, 4,
775                                         &m_CONSTITUENT,
776                                         &m_CONSTITUENTSUFFIX, 
777                                         &m_OBJS,
778                                         &m_LINKMACRO);
779            }
780        }
781    }
782
783  bool need_dependencies = false;
784 
785  for (i = 0; i < m_source_files.size (); i++)
786    {
787      const SourceFile& file = m_source_files[i];
788      Language& language = file.language ();
789      if (language == Language::null () || !language.native_dependencies ())
790        {
791          need_dependencies = true;
792          break;
793        }
794    }
795  dependencies = need_dependencies;
796
797  if (constituent.build_triggers)
798    {
799      dependencies_and_triggers_fragment.copy (m_output_file, 
800                                               constituent.variables, 3,
801                                               &m_CONSTITUENT, 
802                                               &m_CONSTITUENTSUFFIX, 
803                                               &m_LINE);
804    }
805  else
806    {
807      if (need_dependencies)
808        {
809      dependencies_fragment.copy (m_output_file, 
810                                  constituent.variables, 3,
811                                  &m_CONSTITUENT, 
812                                  &m_CONSTITUENTSUFFIX, 
813                                  &m_LINE);
814        }
815    }
816
817  //----------------------------------------------------
818  //
819  // Building actual individual targets.
820  //
821  //----------------------------------------------------
822
823  for (i = 0; i < m_source_files.size (); i++)
824    {
825      SourceFile& file = m_source_files[i];
826      Language& language = file.language ();
827
828      if (language == "java")
829        {
830          java_file_action (file, constituent);
831        }
832      else
833        {
834          module_file_action (file, constituent);
835        }
836    }
837
838  if (m_PACKOS9)
839    {
840      if (os9sources != "")
841        {
842          //
843          // Generate transfers to the OS9 area.
844          //
845
846          m_ALLOS9SOURCES = "";
847          allsources = "";
848        }
849    }
850
851  /*
852    for file in `cmt_sort_line.csh ${os9sources}` ; do
853    if test `echo ${file} | grep '$(src)'` ; then
854    name=`echo ${file} | sed 's#$(src)##'`
855    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
856    allsources="${allsources} ${file}"
857    elif test `echo ${file} | grep '$(inc)'` ; then
858    name=`echo ${file} | sed 's#$(inc)##'`
859    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
860    allsources="${allsources} ${file}"
861    fi
862    done
863
864    if test ! "${ALLOS9SOURCES}" = "" ; then
865
866    sed -e "`subs_vars ALLOS9SOURCES`" \
867    ${os9_header_fragment} \
868    >>${output}
869
870    for FULLNAME in ${allsources} ; do
871
872    NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'`
873
874    sed -e "`subs_vars NAME FULLNAME`" \
875    ${os9_fragment} \
876    >>${output}
877
878    done
879    fi
880    fi
881    fi
882  */
883
884  //
885  //  Generate package cleanup operations.
886  //
887
888  cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, 
889                                &m_CONSTITUENT,
890                                &m_CONSTITUENTSUFFIX);
891
892  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
893  if (need_prototypes)
894    {
895      if (protos != "")
896        {
897          m_FULLNAME = protos;
898          cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
899          m_FULLNAME = m_PROTOSTAMPS;
900          cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
901        }
902    }
903
904  if (m_LINKMACRO == "java")
905    {
906      cleanup_java_fragment.copy (m_output_file, constituent.variables, 1, &m_OBJS);
907
908      if (!is_library)
909        {
910          if (constituent.need_check)
911            {
912              check_java_fragment.copy (m_output_file, constituent.variables, 2, 
913                                        &m_CONSTITUENT,
914                                        &m_CONSTITUENTSUFFIX);
915            }
916        }
917    }
918  else
919    {
920      if (is_library)
921        {
922          cleanup_library_fragment.copy (m_output_file, constituent.variables, 2, 
923                                         &m_CONSTITUENT,
924                                         &m_CONSTITUENTSUFFIX);
925        }
926      else
927        {
928          cleanup_application_fragment.copy (m_output_file, constituent.variables, 2, 
929                                             &m_CONSTITUENT,
930                                             &m_CONSTITUENTSUFFIX);
931          if (m_OBJS != "")
932            {
933              cleanup_objects_fragment.copy (m_output_file, constituent.variables, 3, 
934                                             &m_OBJS,
935                                             &m_CONSTITUENT,
936                                             &m_CONSTITUENTSUFFIX);
937            }
938
939          if (constituent.need_check)
940            {
941              check_application_fragment.copy (m_output_file, constituent.variables, 2, 
942                                               &m_CONSTITUENT,
943                                               &m_CONSTITUENTSUFFIX);
944            }
945        }
946    }
947
948  terminate ();
949}
950
951//--------------------------------------------------
952DocumentGenerator::DocumentGenerator ()
953{
954  m_FILEEXTENSION.set ("FILEEXTENSION");
955
956  document_header_fragment.set ("document_header");
957  dependency_fragment.set ("dependency");
958}
959
960//--------------------------------------------------
961void DocumentGenerator::reset ()
962{
963  AnyDocumentGenerator::reset ();
964  m_FILEEXTENSION = "";
965
966  document_header_fragment.reset ();
967  dependency_fragment.reset ();
968}
969
970//--------------------------------------------------
971void DocumentGenerator::build (const cmt_string& package,
972                               const Constituent& constituent,
973                               bool& dependencies,
974                               const cmt_string& file_name)
975{
976  static cmt_string names;
977  static cmt_string output_dir;
978  static cmt_string name;
979  static cmt_string full_name;
980  static cmt_string compressed_name;
981  static cmt_string suffix;
982  static cmt_string output_suffix;
983  static cmt_string fragment_suffix;
984
985  reset ();
986
987  if (!prepare_output (package, constituent, file_name)) return;
988
989  is_library = false;
990  is_application = false;
991  m_GENERATOR = constituent.generator;
992  m_TITLE = "Document";
993
994  int i;
995
996  //  cout << m_TITLE << " " << m_CONSTITUENT << endl;
997  CmtMessage::info (m_TITLE + " " + m_CONSTITUENT);
998
999  //
1000  // Prepare the include paths.
1001  //
1002
1003  const CmtSystem::cmt_string_vector& includes = constituent.includes;
1004
1005  for (i = 0; i < includes.size (); i++)
1006    {
1007      const cmt_string& subdir = includes[i];
1008
1009      m_PACKINCLUDES += " -I";
1010      m_PACKINCLUDES += subdir;
1011    }
1012
1013  //
1014  // Get the fragment associated with the document style
1015  //
1016
1017  FragmentHandle fragment (m_GENERATOR);
1018
1019  fragment_suffix = fragment.suffix ();
1020
1021  output_suffix = ".";
1022
1023  if (fragment_suffix == "")
1024    {
1025      output_suffix += fragment.name ();
1026    }
1027  else
1028    {
1029      output_suffix += fragment_suffix;
1030    }
1031
1032  //
1033  // Scan the sources.
1034  //
1035
1036  const CmtSystem::cmt_string_vector& sources = constituent.modules;
1037  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
1038  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
1039
1040  //  m_LINE = "";
1041
1042  for (i = 0; i < sources.size (); i++)
1043    {
1044      cmt_string& file = sources[i];
1045
1046      set_full_name (full_name, file);
1047      if (full_name == "") continue;
1048
1049      CmtSystem::compress_path (full_name, compressed_name);
1050      full_name = compressed_name;
1051
1052      static CmtSystem::cmt_string_vector files;
1053
1054      int count = get_all_files (full_name, excludes, selects, files);
1055
1056      //      filter_path (full_name);
1057
1058      /*
1059      if (count > 0)
1060        {
1061          m_LINE += full_name;
1062          m_LINE += " ";
1063        }
1064      */
1065
1066      for (int j = 0; j < files.size (); j++)
1067        {
1068          const cmt_string& name = files[j];
1069
1070          if (name != "") 
1071            {
1072              analyze_file (name, constituent.name, output_suffix);
1073            }
1074        }
1075    }
1076
1077  fill_names_outputs ();
1078  //  fill_outputs ();
1079
1080  //  prepare_use_context ();
1081
1082  m_DATE = CmtSystem::now ();
1083  m_USER = CmtSystem::user ();
1084  m_PACKAGE = package;
1085
1086  if (constituent.has_target_tag)
1087    {
1088      m_HASTARGETTAG = "has_target_tag";
1089    }
1090  else
1091    {
1092      m_HASTARGETTAG = "has_no_target_tag";
1093    }
1094
1095  m_HASDEPENDENCIES = fragment.need_dependencies () ? "has_dependencies" : "has_no_dependencies" ;
1096
1097  make_header_fragment.copy (m_output_file, constituent.variables, 8,
1098                             &m_TITLE, 
1099                             &m_CONSTITUENT,
1100                             &m_CONSTITUENTSUFFIX,
1101                             &m_USER,
1102                             &m_DATE,
1103                             &m_PACKAGE,
1104                             &m_HASTARGETTAG,
1105                             &m_HASDEPENDENCIES
1106                             );
1107
1108  const cmt_string& header = fragment.header ();
1109
1110  //
1111  // If the document type specifies a header, use it .
1112  // otherwise, use the default document header fragment.
1113  //
1114  if (header != "")
1115    {
1116      FragmentHandle header_fragment (header);
1117      header_fragment.copy (m_output_file, constituent.variables, 4, 
1118                            &m_CONSTITUENT,
1119                            &m_CONSTITUENTSUFFIX,
1120                            &m_OBJS,
1121                            &m_LINE);
1122    }
1123  else
1124    {
1125      document_header_fragment.copy (m_output_file, constituent.variables, 3, 
1126                                     &m_CONSTITUENT,
1127                                     &m_CONSTITUENTSUFFIX,
1128                                     &m_OBJS);
1129    }
1130
1131  dependencies = fragment.need_dependencies ();
1132  if (fragment.need_dependencies ())
1133    {
1134      dependencies_fragment.copy (m_output_file, constituent.variables, 3, 
1135                                  &m_CONSTITUENT,
1136                                  &m_CONSTITUENTSUFFIX,
1137                                  &m_LINE);
1138    }
1139  else
1140    {
1141      /*
1142      for (i = 0; i < sources.size (); i++)
1143        {
1144          cmt_string& file = sources[i];
1145         
1146          set_full_name (full_name, file);
1147          if (full_name == "") continue;
1148         
1149          CmtSystem::compress_path (full_name, compressed_name);
1150          full_name = compressed_name;
1151
1152          static CmtSystem::cmt_string_vector files;
1153         
1154          get_all_files (full_name, excludes, selects, files);
1155         
1156          for (int j = 0; j < files.size (); j++)
1157            {
1158              const cmt_string& name = files[j];
1159      */             
1160      for (i = 0; i < m_source_files.size (); i++)
1161        {
1162          SourceFile& file = m_source_files[i];
1163          const cmt_string& name = file.name ();
1164              if (name != "") 
1165                {
1166                  static cmt_string s;
1167                  static cmt_string n;
1168                 
1169                  CmtSystem::get_dot_suffix (name, s);
1170                  CmtSystem::basename (name, s, n);
1171                  CmtSystem::get_suffix (name, s);
1172                 
1173                  fprintf (m_output_file, "%s_%s_dependencies = %s\n",
1174                           n.c_str (),
1175                           s.c_str (),
1176                           name.c_str ());
1177                }
1178              //            }
1179        }
1180    }
1181 
1182  m_SUFFIX = fragment_suffix;
1183  for (i = 0; i < m_source_files.size (); i++)
1184    {
1185      SourceFile& file = m_source_files[i];
1186      const cmt_string& file_name = file.name ();
1187      m_OUTPUTNAME = file.output ();
1188      m_FULLNAME = file_name;
1189      CmtSystem::get_dot_suffix (file_name, suffix);
1190      CmtSystem::basename (file_name, suffix, m_NAME.value);
1191      CmtSystem::dirname (file_name, m_FILEPATH.value);
1192      if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
1193      filter_path (m_FILEPATH.value);
1194      m_FILENAME.value = m_NAME.value + suffix;
1195      //CmtSystem::basename (file_name, m_FILENAME.value);
1196      m_FILESUFFIX.value = suffix;
1197      //CmtSystem::get_dot_suffix (m_FILENAME.value, m_FILESUFFIX.value);
1198      CmtSystem::get_suffix (m_FILENAME.value, m_FILEEXTENSION.value);
1199      /*
1200      if (!CmtSystem::test_file (file_name) && !CmtSystem::test_directory (file_name))
1201        {
1202          CmtMessage::warning ("Source file " + file_name + " not found");
1203        }
1204      */
1205      filter_path (m_FULLNAME.value);
1206
1207      if (fragment.need_dependencies ())
1208        {
1209          // ensure that ${CONSTITUENT}_dependencies.make gets rebuilt
1210          // whenever source file OR its dependencies change
1211          if (!dependency_fragment.copy (m_output_file, constituent.variables, 10,
1212                                         &m_FILEPATH,
1213                                         &m_SUFFIX,
1214                                         &m_OUTPUTNAME,
1215                                         &m_CONSTITUENT,
1216                                         &m_CONSTITUENTSUFFIX,
1217                                         &m_FILENAME,
1218                                         &m_NAME,
1219                                         &m_FULLNAME,
1220                                         &m_FILESUFFIX,
1221                                         &m_FILEEXTENSION)) return;
1222        }
1223     
1224      fragment.copy (m_output_file, constituent.variables, 10,
1225                     &m_FILEPATH,
1226                     &m_SUFFIX,
1227                     &m_OUTPUTNAME,
1228                     &m_CONSTITUENT,
1229                     &m_CONSTITUENTSUFFIX,
1230                     &m_FILENAME,
1231                     &m_NAME,
1232                     &m_FULLNAME,
1233                     &m_FILESUFFIX,
1234                     &m_FILEEXTENSION);
1235    }
1236
1237  const cmt_string& trailer = fragment.trailer ();
1238  if (trailer != "")
1239    {
1240      FragmentHandle trailer_fragment (trailer);
1241      trailer_fragment.copy (m_output_file, constituent.variables, 4, 
1242                             &m_CONSTITUENT,
1243                             &m_CONSTITUENTSUFFIX,
1244                             &m_OBJS,
1245                             &m_LINE);
1246    }
1247
1248  //
1249  //  Generate package cleanup operations.
1250  //
1251
1252  cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, 
1253                                &m_CONSTITUENT,
1254                                &m_CONSTITUENTSUFFIX);
1255
1256  terminate ();
1257}
1258
1259//--------------------------------------------------
1260bool DocumentGenerator::analyze_file (const cmt_string& file,
1261                                      const cmt_string& constituent_name,
1262                                      const cmt_string& output_suffix)
1263{
1264  //static cmt_string output_dir;
1265  static cmt_string suffix;
1266  static cmt_string name;
1267  static cmt_string obj;
1268
1269  if (!CmtSystem::test_file (file) && !CmtSystem::test_directory (file))
1270    {
1271      CmtMessage::warning ("Source file " + file + " not found");
1272    }
1273
1274  //CmtSystem::dirname (file, output_dir);
1275  //output_dir += CmtSystem::file_separator ();
1276
1277  //filter_path (output_dir);
1278
1279  CmtSystem::get_suffix (file, suffix);
1280  CmtSystem::basename (file, suffix, name);
1281
1282  //obj = output_dir;
1283  obj = "$(";
1284  obj += constituent_name;
1285  obj += "_output)";
1286  obj += name;
1287  obj += output_suffix;
1288
1289  SourceFile& source = m_source_files.add ();
1290  source.set (file, Language::null (), obj);
1291
1292  return (true);
1293}
1294
1295//--------------------------------------------------
1296ReadmeGenerator::ReadmeGenerator ()
1297{
1298  readme_header_fragment.set ("readme_header");
1299  readme_fragment.set ("readme");
1300  readme_doc_fragment.set ("readme_doc");
1301  readme_use_fragment.set ("readme_use");
1302  readme_trailer_fragment.set ("readme_trailer");
1303}
1304
1305void ReadmeGenerator::reset ()
1306{
1307  CmtGenerator::reset ();
1308
1309  readme_header_fragment.reset ();
1310  readme_fragment.reset ();
1311  readme_doc_fragment.reset ();
1312  readme_use_fragment.reset ();
1313  readme_trailer_fragment.reset ();
1314}
1315
1316//--------------------------------------------------
1317void ReadmeGenerator::build (const CmtSystem::cmt_string_vector& arguments)
1318{
1319  reset ();
1320
1321  m_PACKAGE = Cmt::get_current_package ();
1322  m_VERSION = Cmt::get_current_version ();
1323  m_DATE = CmtSystem::now ();
1324  m_USER = CmtSystem::user ();
1325
1326  cmt_string url;
1327  cmt_string doc;
1328
1329  for (int i = 0; i < arguments.size (); i++)
1330    {
1331      cmt_string arg = arguments[i];
1332
1333      if (arg.substr (0, 5) == "-url=")
1334        {
1335          arg.substr (5, url);
1336        }
1337      else if (arg.substr (0, 5) == "-doc=")
1338        {
1339          arg.substr (5, doc);
1340        }
1341    }
1342
1343  m_output_file_name = cmtdir + "README.html";
1344
1345  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1346  if (m_output_file != NULL)
1347    {
1348      readme_header_fragment.copy (m_output_file, 2, 
1349                                   &m_PACKAGE, &m_VERSION);
1350
1351      if (doc != "")
1352        {
1353          m_DOCPATH = doc;
1354          readme_doc_fragment.copy (m_output_file, 3,
1355                                    &m_PACKAGE,
1356                                    &m_VERSION,
1357                                    &m_DOCPATH);
1358        }
1359
1360      readme_fragment.copy (m_output_file, 2,
1361                            &m_PACKAGE,
1362                            &m_VERSION);
1363
1364      int number;
1365      const Use::UsePtrVector& uses = Use::get_ordered_uses ();
1366
1367      for (number = 0; number < uses.size (); number++)
1368        {
1369          const Use* use = uses[number];
1370
1371          if (use == 0) continue;
1372          if (use->discarded) continue;
1373
1374          Package* p = use->get_package ();
1375          if (p->is_cmt ()) continue;
1376
1377          cmt_string selected_path;
1378
1379          if (url == "")
1380            {
1381              selected_path = use->real_path;
1382             
1383              if (use->specified_path != "")
1384                {
1385                  int pos = selected_path.find_last_of (use->specified_path);
1386                  if (pos != cmt_string::npos)
1387                    {
1388                      selected_path.erase (pos);
1389                    }
1390                }
1391            }
1392          else
1393            {
1394              selected_path = url;
1395             
1396              if (use->specified_path != "")
1397                {
1398                  selected_path += CmtSystem::file_separator ();
1399                }
1400            }
1401         
1402          m_PACKAGEPATH = selected_path;
1403          m_PACKAGEPREFIX = use->specified_path;
1404          m_PACKAGE = use->get_package_name ();
1405          m_VERSION = use->version;
1406          m_MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt";
1407          readme_use_fragment.copy (m_output_file, 5,
1408                                    &m_PACKAGEPATH,
1409                                    &m_PACKAGEPREFIX,
1410                                    &m_PACKAGE,
1411                                    &m_VERSION,
1412                                    &m_MGRSTYLE);
1413        }
1414
1415      m_PACKAGE = Cmt::get_current_package ();
1416      m_VERSION = Cmt::get_current_version ();
1417      readme_trailer_fragment.copy (m_output_file, 4, 
1418                                    &m_PACKAGE, 
1419                                    &m_VERSION, 
1420                                    &m_DATE, 
1421                                    &m_USER);
1422
1423      terminate ();
1424    }
1425  else
1426    {
1427      CmtError::set (CmtError::file_access_error, m_output_file_name);
1428    }
1429}
1430
1431//--------------------------------------------------
1432class Prototyper : public FAwk
1433{
1434public:
1435  Prototyper (bool static_functions = false) :
1436    m_static_functions(static_functions)
1437  {
1438    if (m_static_functions)
1439      {
1440        m_suffix = "_static.phnew";
1441        m_define_suffix = "_static_ph";
1442      }
1443    else
1444      {
1445        m_suffix = ".phnew";
1446        m_define_suffix = "_ph";
1447      }
1448  }
1449
1450  void begin ()
1451  {
1452    m_running = false;
1453
1454    static cmt_string suffix;
1455    static cmt_string name;
1456
1457    CmtSystem::get_dot_suffix (m_file_name, suffix);
1458    CmtSystem::basename (m_file_name, suffix, name);
1459
1460    m_out_file_name  = "";
1461
1462    if (m_dir_name != "")
1463      {
1464        m_out_file_name  = m_dir_name;
1465        m_out_file_name += CmtSystem::file_separator ();
1466      }
1467
1468    m_out_file_name += name;
1469    m_out_file_name += m_suffix;
1470
1471    CmtSystem::basename (m_file_name, suffix, m_file_name);
1472
1473    m_output = fopen (m_out_file_name.c_str (), "wb");
1474
1475    if (m_output != 0)
1476      {
1477        fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (),
1478                 m_define_suffix.c_str ());
1479        fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (),
1480                 m_define_suffix.c_str ());
1481
1482        fprintf (m_output, "\n");
1483        fprintf (m_output, "#ifdef __cplusplus\n");
1484        fprintf (m_output, "extern \"C\" {\n");
1485        fprintf (m_output, "#endif\n");
1486        fprintf (m_output, "\n");
1487      }
1488    else
1489      {
1490        stop ();
1491      }
1492  }
1493
1494  void filter (const cmt_string& line)
1495  {
1496    char c = line[0];
1497
1498    if (!m_running)
1499      {
1500        if ((c == ' ') ||
1501            (c == '/') ||
1502            (c == '|') ||
1503            (c == '\t') ||
1504            (c == '#')) return;
1505        if (line.find ('(') == cmt_string::npos)
1506          {
1507            m_prev_line = line;
1508            return;
1509          }
1510
1511        m_running = true;
1512        m_full_line = line;
1513        m_full_line.replace ("(", " (");
1514
1515        static CmtSystem::cmt_string_vector words;
1516
1517        CmtSystem::split (m_full_line, " \t", words);
1518
1519        const cmt_string& second = words[1];
1520        if (second[0] == '(')
1521          {
1522            m_full_line = m_prev_line;
1523            m_full_line += " ";
1524            m_full_line += line;
1525
1526            m_prev_line = "";
1527          }
1528      }
1529    else
1530      {
1531        m_full_line += line;
1532      }
1533    if (line.find (')') == cmt_string::npos) return;
1534    m_running = false;
1535
1536    if (m_full_line.find (';') != cmt_string::npos) return;
1537    if (m_full_line.find ("::") != cmt_string::npos) return;
1538    if (m_full_line.find ('<') != cmt_string::npos) return;
1539    if (m_full_line.find ('>') != cmt_string::npos) return;
1540    if (m_full_line.find ('{') != cmt_string::npos) return;
1541    if (m_full_line.find ('}') != cmt_string::npos) return;
1542    if (m_full_line.find ("typedef") != cmt_string::npos) return;
1543    if (m_full_line.find ("yy") != cmt_string::npos) return;
1544    if (m_full_line.find ("YY") != cmt_string::npos) return;
1545    if (m_static_functions)
1546      {
1547        if (m_full_line.find ("static") == cmt_string::npos) return;
1548      }
1549    else
1550      {
1551        if (m_full_line.find ("static") != cmt_string::npos) return;
1552      }
1553
1554    m_full_line += ";";
1555
1556    if (m_output != 0)
1557      {
1558        fprintf (m_output, "%s\n", m_full_line.c_str ());
1559      }
1560  }
1561
1562  void end ()
1563  {
1564    if (m_output != 0)
1565      {
1566        fprintf (m_output, "\n");
1567        fprintf (m_output, "#ifdef __cplusplus\n");
1568        fprintf (m_output, "}\n");
1569        fprintf (m_output, "#endif\n");
1570        fprintf (m_output, "\n");
1571        fprintf (m_output, "#endif\n");
1572        fprintf (m_output, "\n");
1573
1574        fclose (m_output);
1575      }
1576
1577    CmtGenerator::check (m_out_file_name);
1578  }
1579
1580private:
1581  bool m_running;
1582  cmt_string m_out_file_name;
1583  FILE* m_output;
1584  bool m_static_functions;
1585  cmt_string m_full_line;
1586  cmt_string m_prev_line;
1587  cmt_string m_suffix;
1588  cmt_string m_define_suffix;
1589};
1590//--------------------------------------------------
1591
1592//--------------------------------------------------
1593void PrototypeGenerator::build (const cmt_string& file_name)
1594{
1595  Prototyper prototyper;
1596
1597  reset ();
1598
1599  prototyper.run (file_name);
1600}
1601
1602//--------------------------------------------------
1603void DefaultMakefileGenerator::build ()
1604{
1605  cmt_string makefile;
1606
1607  //reset ();
1608
1609  //--- Build a simple Makefile if none is installed
1610
1611#ifndef WIN32
1612
1613  bool need_makefile = false;
1614
1615  makefile = cmtdir + "Makefile";
1616
1617  if (!CmtSystem::test_file (makefile))
1618    {
1619      need_makefile = true;
1620    }
1621  else
1622    {
1623      static cmt_string s;
1624
1625      s.read (makefile);
1626      if ((s.find ("METHODSROOT") != cmt_string::npos) ||
1627          (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos))
1628        {
1629          static cmt_string backup = makefile;
1630          backup += "_backup";
1631
1632          makefile += ".cmt";
1633
1634          if (!CmtSystem::test_file (makefile))
1635            {
1636              FILE* file = fopen (backup.c_str (), "wb");
1637              if (file != NULL)
1638                {
1639                  CmtMessage::warning ("\n"
1640                                       "# A Makefile already exists "
1641                                       "but it does not provide\n"
1642                                       "# the recommended features "
1643                                       "for a full benefit of CMT\n"
1644                                       "#\n"
1645                                       "# CMT is now building "
1646                                       "a new 'Makefile.cmt' which you can use\n"
1647                                       "# to upgrade your current one.");
1648                  /*
1649                  cerr << "# " << endl;
1650                  cerr << "#CMT> Warning: " << endl;
1651                  cerr << "# A Makefile already exists "
1652                    "but it does not provides " << endl;
1653                  cerr << "# the recommended features "
1654                    "for a full benefit of CMT" << endl;
1655                  cerr << "# " << endl;
1656                  cerr << "# CMT is now building "
1657                    "a new 'Makefile.cmt' which you can use" << endl;
1658                  cerr << "# to upgrade your current one." << endl;
1659                  cerr << "# " << endl;
1660                  */
1661                  s.write (file);
1662                  CmtSystem::close_ostream (file, backup);
1663                  //  fclose (file);
1664
1665                  need_makefile = true;
1666                }
1667              else
1668                {
1669                  CmtError::set (CmtError::file_access_error, backup);
1670                }
1671            }
1672        }
1673    }
1674
1675  if (need_makefile)
1676    {
1677      FILE* file = fopen (makefile.c_str (), "wb");
1678      if (file != NULL)
1679        {
1680          fprintf (file,
1681                   "include $(CMTROOT)/src/Makefile.header\n"
1682                   "\n"
1683                   "include $(CMTROOT)/src/constituents.make\n"
1684                   "\n");
1685          CmtSystem::close_ostream (file, makefile);
1686          //          fclose (file);
1687        }
1688      else
1689        {
1690          CmtError::set (CmtError::file_access_error, makefile);
1691        }
1692    }
1693
1694#endif
1695
1696#ifdef WIN32
1697
1698  makefile = cmtdir + "NMake";
1699
1700  if (Cmt::get_debug ())
1701    {
1702      cout << "DefaultMakefileGenerator::build> pwd=" << CmtSystem::pwd () << " cmtdir=" << cmtdir << endl;
1703    }
1704
1705  if (!CmtSystem::test_file (makefile))
1706    {
1707      FILE* file = fopen (makefile.c_str (), "wb");
1708      if (file != NULL)
1709        {
1710          fprintf (file,
1711                   "!include $(CMTROOT)\\src\\NMakefile.header\n"
1712                   "\n"
1713                   "!include $(CMTROOT)\\src\\constituents.nmake\n"
1714                   "\n");
1715          CmtSystem::close_ostream (file, makefile);
1716          //          fclose (file);
1717        }
1718      else
1719        {
1720          CmtError::set (CmtError::file_access_error, makefile);
1721        }
1722    }
1723
1724#endif
1725
1726}
1727
1728MSDEVGenerator::MSDEVGenerator ()
1729{
1730  dsw_header_fragment.set ("dsw_header");
1731  dsw_project_fragment.set ("dsw_project");
1732  dsw_all_project_header_fragment.set ("dsw_all_project_header");
1733  dsw_all_project_dependency_fragment.set ("dsw_all_project_dependency");
1734  dsw_all_project_trailer_fragment.set ("dsw_all_project_trailer");
1735  dsw_trailer_fragment.set ("dsw_trailer");
1736
1737  dsp_all_fragment.set ("dsp_all");
1738  dsp_library_header_fragment.set ("dsp_library_header");
1739  dsp_application_header_fragment.set ("dsp_application_header");
1740  dsp_windows_header_fragment.set ("dsp_windows_header");
1741  dsp_contents_fragment.set ("dsp_contents");
1742  dsp_trailer_fragment.set ("dsp_trailer");
1743}
1744
1745void MSDEVGenerator::reset ()
1746{
1747  CmtGenerator::reset ();
1748
1749  dsw_header_fragment.reset ();
1750  dsw_project_fragment.reset ();
1751  dsw_all_project_header_fragment.reset ();
1752  dsw_all_project_dependency_fragment.reset ();
1753  dsw_all_project_trailer_fragment.reset ();
1754  dsw_trailer_fragment.reset ();
1755
1756  dsp_all_fragment.reset ();
1757  dsp_library_header_fragment.reset ();
1758  dsp_application_header_fragment.reset ();
1759  dsp_windows_header_fragment.reset ();
1760  dsp_contents_fragment.reset ();
1761  dsp_trailer_fragment.reset ();
1762
1763  CmtSystem::cd (Cmt::get_current_dir ());
1764
1765  cmt_string branch = CmtSystem::current_branch ();
1766
1767  if ((branch == "mgr") || (branch == "cmt"))
1768    {
1769#ifdef WIN32
1770      msdevdir = "..";
1771      msdevdir += CmtSystem::file_separator ();
1772      msdevdir += "Visual";
1773     
1774      if (!CmtSystem::test_directory (msdevdir))
1775        {
1776          CmtSystem::mkdir (msdevdir);
1777        }
1778     
1779      msdevdir += CmtSystem::file_separator ();
1780#endif
1781    }
1782  else
1783    {
1784#ifdef WIN32
1785      msdevdir = ".";
1786      msdevdir += CmtSystem::file_separator ();
1787#endif
1788    }
1789
1790}
1791
1792int MSDEVGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
1793{
1794  reset ();
1795
1796  const cmt_string& package = Cmt::get_current_package ();
1797
1798  m_output_file_name = msdevdir + package + ".dswnew";
1799
1800  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1801  if (m_output_file != NULL)
1802    {
1803      m_PACKAGE = package;
1804      dsw_header_fragment.wincopy (m_output_file, 1,
1805                                   &m_PACKAGE);
1806
1807      int i;
1808
1809      dsw_all_project_header_fragment.wincopy (m_output_file, 1, 
1810                                               &m_PACKAGE);
1811
1812      for (i = 0; i < constituents.size (); i++)
1813        {
1814          const Constituent& constituent = constituents[i];
1815
1816          if (constituent.type == Library)
1817            {
1818              m_CONSTITUENT = constituent.name;
1819              m_CONSTITUENTSUFFIX = constituent.suffix;
1820              dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1821                                                           &m_PACKAGE,
1822                                                           &m_CONSTITUENT, 
1823                                                           &m_CONSTITUENTSUFFIX);
1824            }
1825          else
1826            {
1827              m_CONSTITUENT = constituent.name;
1828              m_CONSTITUENTSUFFIX = constituent.suffix;
1829              dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1830                                                           &m_PACKAGE,
1831                                                           &m_CONSTITUENT, 
1832                                                           &m_CONSTITUENTSUFFIX);
1833            }
1834
1835        }
1836
1837      dsw_all_project_trailer_fragment.wincopy (m_output_file,
1838                                                1, &m_PACKAGE);
1839
1840      for (i = 0; i < constituents.size (); i++)
1841        {
1842          const Constituent& constituent = constituents[i];
1843
1844          if (constituent.type == Library)
1845            {
1846              m_CONSTITUENT = constituent.name;
1847              m_CONSTITUENTSUFFIX = constituent.suffix;
1848              dsw_project_fragment.wincopy (m_output_file,
1849                                            constituent.variables, 3,
1850                                            &m_PACKAGE,
1851                                            &m_CONSTITUENT, 
1852                                            &m_CONSTITUENTSUFFIX);
1853            }
1854          else
1855            {
1856              m_CONSTITUENT = constituent.name;
1857              m_CONSTITUENTSUFFIX = constituent.suffix;
1858              dsw_project_fragment.wincopy (m_output_file, constituent.variables, 3, 
1859                                            &m_PACKAGE,
1860                                            &m_CONSTITUENT, 
1861                                            &m_CONSTITUENTSUFFIX);
1862            }
1863        }
1864
1865      dsw_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1866
1867      terminate ();
1868    }
1869  else
1870    {
1871      CmtError::set (CmtError::file_access_error, m_output_file_name);
1872    }
1873
1874  m_output_file_name = msdevdir + "all.dspnew";
1875
1876  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1877  if (m_output_file != NULL)
1878    {
1879      dsp_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1880      terminate ();
1881    }
1882  else
1883    {
1884      CmtError::set (CmtError::file_access_error, m_output_file_name);
1885    }
1886
1887  return (0);
1888}
1889
1890//--------------------------------------------------
1891int MSDEVGenerator::build_project (const Constituent& constituent)
1892{
1893  reset ();
1894
1895  const cmt_string& package = Cmt::get_current_package ();
1896  static cmt_string file;
1897  static cmt_string full_name;
1898  static cmt_string suffix;
1899
1900  int i;
1901
1902  m_CONSTITUENT = constituent.name;
1903  m_CONSTITUENTSUFFIX = constituent.suffix;
1904
1905  for (i = 0; i < constituent.includes.size (); i++)
1906    {
1907      const cmt_string& include = constituent.includes[i];
1908      m_PACKINCLUDES += " -I" + include;
1909    }
1910
1911  switch (constituent.type)
1912    {
1913    case Application:
1914      is_application = true;
1915      m_TITLE = "Application";
1916      break;
1917    case Library:
1918      is_library = true;
1919      m_TITLE = "Library";
1920      break;
1921    case Document:
1922      m_GENERATOR = constituent.generator;
1923      m_TITLE = "Document";
1924      break;
1925    }
1926
1927  m_PACKOS9 = constituent.need_OS9;
1928
1929  const CmtSystem::cmt_string_vector& sources = constituent.modules;
1930  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
1931  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
1932
1933  //--- Build the constituents fragment -----
1934
1935  m_output_file_name = msdevdir + m_CONSTITUENT + ".dspnew";
1936  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1937
1938  if (m_output_file == NULL) return (0);
1939
1940  m_PACKAGE = package;
1941
1942  if (is_library)
1943    {
1944      if (constituent.no_share)
1945        {
1946          m_LIBRARYSUFFIX = "lib";
1947        }
1948      else
1949        {
1950          m_LIBRARYSUFFIX = "arc";
1951        }
1952
1953      dsp_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
1954                                           &m_PACKAGE,
1955                                           &m_CONSTITUENT, 
1956                                           &m_CONSTITUENTSUFFIX, 
1957                                           &m_LIBRARYSUFFIX);
1958    }
1959  else
1960    {
1961      if (constituent.windows)
1962        {
1963          dsp_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1964                                               &m_PACKAGE,
1965                                               &m_CONSTITUENT, 
1966                                               &m_CONSTITUENTSUFFIX);
1967        }
1968      else
1969        {
1970          dsp_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1971                                                   &m_PACKAGE,
1972                                                   &m_CONSTITUENT, 
1973                                                   &m_CONSTITUENTSUFFIX);
1974        }
1975    }
1976
1977  for (i = 0; i < sources.size (); i++)
1978    {
1979      file = sources[i];
1980
1981      set_full_name (full_name, file);
1982      if (full_name == "") continue;
1983
1984      static CmtSystem::cmt_string_vector files;
1985
1986      get_all_files (full_name, excludes, selects, files);
1987
1988      for (int j = 0; j < files.size (); j++)
1989        {
1990          const cmt_string& name = files[j];
1991
1992          if (name != "") 
1993            {
1994              m_FULLNAME = name;
1995
1996              if (m_output_file != NULL)
1997                {
1998                  dsp_contents_fragment.wincopy (m_output_file, constituent.variables, 2, 
1999                                                 &m_PACKAGE, 
2000                                                 &m_FULLNAME);
2001                }
2002            }
2003        }
2004    }
2005
2006  if (m_output_file != NULL)
2007    {
2008      dsp_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
2009                                    &m_PACKAGE,
2010                                    &m_CONSTITUENT, 
2011                                    &m_CONSTITUENTSUFFIX);
2012
2013      terminate ();
2014    }
2015
2016  return (0);
2017}
2018
2019
2020VSNETGenerator::VSNETGenerator ()
2021{
2022  sln_header_fragment.set ("sln_header");
2023  sln_project_fragment.set ("sln_project");
2024  sln_dependency_header_fragment.set ("sln_dependency_header");
2025  sln_dependency_project_fragment.set ("sln_dependency_project");
2026  sln_dependency_trailer_fragment.set ("sln_dependency_trailer");
2027  sln_project_config_fragment.set ("sln_project_config");
2028  sln_trailer_fragment.set ("sln_trailer");
2029
2030  vcproj_all_fragment.set ("vcproj_all");
2031  vcproj_library_header_fragment.set ("vcproj_library_header");
2032  vcproj_application_header_fragment.set ("vcproj_application_header");
2033  vcproj_windows_header_fragment.set ("vcproj_windows_header");
2034  vcproj_contents_fragment.set ("vcproj_contents");
2035  vcproj_directory_header_fragment.set ("vcproj_directory_header");
2036  vcproj_directory_trailer_fragment.set ("vcproj_directory_trailer");
2037  vcproj_trailer_fragment.set ("vcproj_trailer");
2038}
2039
2040void VSNETGenerator::reset ()
2041{
2042  CmtGenerator::reset ();
2043
2044  CmtSystem::cd (Cmt::get_current_dir ());
2045
2046  cmt_string branch = CmtSystem::current_branch ();
2047
2048  if ((branch == "mgr") || (branch == "cmt"))
2049    {
2050#ifdef WIN32
2051      vsnetdir = "..";
2052      vsnetdir += CmtSystem::file_separator ();
2053      vsnetdir += "Visual";
2054     
2055      if (!CmtSystem::test_directory (vsnetdir))
2056        {
2057          CmtSystem::mkdir (vsnetdir);
2058        }
2059     
2060      vsnetdir += CmtSystem::file_separator ();
2061#endif
2062    }
2063  else
2064    {
2065#ifdef WIN32
2066      vsnetdir = ".";
2067      vsnetdir += CmtSystem::file_separator ();
2068#endif
2069    }
2070}
2071
2072void VSNETGenerator::pseudoGUID (const cmt_string& a, 
2073                                 const cmt_string& b, 
2074                                 const cmt_string& c, 
2075                                 cmt_string& d)
2076{
2077  char buf[64]; // make the guid in here
2078  static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
2079  int k = 0;
2080  int i;
2081
2082  for (i = 0; (i < c.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = c[i];
2083  for (i = 0; (i < a.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = a[i];
2084  for (i = 0; (i < b.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = b[i];
2085  for (; k < sizeof(buf); ++k) buf[k] = 0;
2086
2087  // now use the buffer to format the output string
2088  // example: {3FE091FC-3738-4F2E-9723-E846B43F77AB}
2089  d = '{';
2090  k = 0;
2091
2092  for (i = 0; i < 4; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
2093  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
2094  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
2095  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
2096  for (i = 0; i < 6; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '}';
2097}
2098
2099int VSNETGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
2100{
2101  reset ();
2102
2103  const cmt_string& package = Cmt::get_current_package ();
2104 
2105  m_output_file_name = vsnetdir + package + ".slnnew";
2106 
2107  Variable PACKAGE_GUID ("PACKAGE_GUID");
2108  Variable CONSTITUENT_GUID ("CONSTITUENT_GUID");
2109  Variable NUMBER ("NUMBER");
2110 
2111  cmt_string guid;
2112  pseudoGUID (package, Cmt::get_current_version(), "", guid);
2113  PACKAGE_GUID = guid;
2114 
2115  m_output_file = fopen (m_output_file_name.c_str (), "wb");
2116 
2117  if (m_output_file != NULL)
2118    {
2119      m_PACKAGE = package;
2120      sln_header_fragment.wincopy (m_output_file, 2, 
2121                                   &m_PACKAGE,
2122                                   &PACKAGE_GUID);
2123     
2124      int i;
2125     
2126      for (i = 0; i < constituents.size (); i++)
2127        {
2128          const Constituent& constituent = constituents[i];
2129         
2130          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2131          CONSTITUENT_GUID = guid;
2132         
2133          if (constituent.type == Library)
2134            {
2135              m_CONSTITUENT = constituent.name;
2136              m_CONSTITUENTSUFFIX = constituent.suffix;
2137              sln_project_fragment.wincopy (m_output_file,
2138                                            constituent.variables, 4,
2139                                            &m_PACKAGE,
2140                                            &m_CONSTITUENT,
2141                                            &PACKAGE_GUID,
2142                                            &CONSTITUENT_GUID);
2143            }
2144          else
2145            {
2146              m_CONSTITUENT = constituent.name;
2147              m_CONSTITUENTSUFFIX = constituent.suffix;
2148              sln_project_fragment.wincopy (m_output_file, constituent.variables, 4,
2149                                            &m_PACKAGE,
2150                                            &m_CONSTITUENT,
2151                                            &PACKAGE_GUID,
2152                                            &CONSTITUENT_GUID);
2153            }
2154        }
2155     
2156      sln_dependency_header_fragment.wincopy (m_output_file,
2157                                              1, &m_PACKAGE);
2158     
2159      for (i = 0; i < constituents.size (); i++)
2160        {
2161          const Constituent& constituent = constituents[i];
2162          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2163          CONSTITUENT_GUID = guid;
2164         
2165          cmt_string num;
2166          num = (char)('0' + i);
2167          NUMBER = num;
2168          if (constituent.type == Library)
2169            {
2170              m_CONSTITUENT = constituent.name;
2171              m_CONSTITUENTSUFFIX = constituent.suffix;
2172             
2173              sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
2174                                                       &m_PACKAGE,
2175                                                       &m_CONSTITUENT,
2176                                                       &PACKAGE_GUID,
2177                                                       &CONSTITUENT_GUID,
2178                                                       &NUMBER);
2179            }
2180          else
2181            {
2182              m_CONSTITUENT = constituent.name;
2183              m_CONSTITUENTSUFFIX = constituent.suffix;
2184              sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
2185                                                       &m_PACKAGE,
2186                                                       &m_CONSTITUENT,
2187                                                       &PACKAGE_GUID,
2188                                                       &CONSTITUENT_GUID, 
2189                                                       &NUMBER);
2190            }
2191        }
2192     
2193      sln_dependency_trailer_fragment.wincopy (m_output_file,
2194                                               1, &m_PACKAGE);
2195     
2196      for (i = 0; i < constituents.size (); i++)
2197        {
2198          const Constituent& constituent = constituents[i];
2199          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2200          CONSTITUENT_GUID = guid;
2201         
2202          if (constituent.type == Library)
2203            {
2204              m_CONSTITUENT = constituent.name;
2205              m_CONSTITUENTSUFFIX = constituent.suffix;
2206              sln_project_config_fragment.wincopy (m_output_file,
2207                                                   constituent.variables, 3,
2208                                                   &m_PACKAGE,
2209                                                   &m_CONSTITUENT,
2210                                                   &CONSTITUENT_GUID);
2211            }
2212          else
2213            {
2214              m_CONSTITUENT = constituent.name;
2215              m_CONSTITUENTSUFFIX = constituent.suffix;
2216              sln_project_config_fragment.wincopy (m_output_file, constituent.variables, 3,
2217                                                   &m_PACKAGE,
2218                                                   &m_CONSTITUENT,
2219                                                   &CONSTITUENT_GUID);
2220            }
2221        }
2222     
2223      sln_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
2224
2225      terminate ();
2226    }
2227 
2228  m_output_file_name = vsnetdir + "all.vcprojnew";
2229 
2230  m_output_file = fopen (m_output_file_name.c_str (), "wb");
2231  if (m_output_file != NULL)
2232    {
2233      vcproj_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
2234
2235      terminate ();
2236    }
2237 
2238  return (0);
2239}
2240
2241int VSNETGenerator::build_project (const Constituent& constituent)
2242{
2243  reset ();
2244 
2245  const cmt_string& package = Cmt::get_current_package();
2246  static cmt_string file;
2247  static cmt_string full_name;
2248  static cmt_string suffix;
2249 
2250  static Variable GUID("GUID");
2251  int i;
2252 
2253  // Directory Support
2254  int dir_pos;
2255  int file_pos;
2256  int src_pos;
2257  int iSFFilter = 0;
2258  cmt_string directory;
2259  cmt_string new_dir;
2260  bool need_trailer = false;
2261
2262  m_CONSTITUENT = constituent.name;
2263  // make up a pseudo-GUID from the constituent-pacakge-version combination
2264 
2265  cmt_string guid;
2266  pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2267 
2268  GUID = guid;
2269 
2270  for (i = 0; i < constituent.includes.size (); i++)
2271    {
2272      const cmt_string& include = constituent.includes[i];
2273      m_PACKINCLUDES += " -I" + include;
2274    }
2275 
2276  switch (constituent.type)
2277    {
2278    case Application:
2279      is_application = true;
2280      m_TITLE = "Application";
2281      break;
2282    case Library:
2283      is_library = true;
2284      m_TITLE = "Library";
2285      break;
2286    case Document:
2287      m_GENERATOR = constituent.generator;
2288      m_TITLE = "Document";
2289      break;
2290    }
2291 
2292  m_PACKOS9 = constituent.need_OS9;
2293 
2294  const CmtSystem::cmt_string_vector& sources = constituent.modules;
2295  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
2296  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
2297 
2298  //--- Build the constituents fragment -----
2299  cmt_string output;
2300 
2301  m_output_file_name = vsnetdir + m_CONSTITUENT + ".vcprojnew";
2302  m_output_file = fopen (m_output_file_name.c_str (), "wb");
2303 
2304  if (m_output_file == NULL) return (0);
2305 
2306  m_PACKAGE = package;
2307 
2308  if (is_library)
2309    {
2310      if (constituent.no_share)
2311        {
2312          m_LIBRARYSUFFIX = "lib";
2313        }
2314      else
2315        {
2316          m_LIBRARYSUFFIX = "arc";
2317        }
2318     
2319      vcproj_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
2320                                              &m_PACKAGE,
2321                                              &m_CONSTITUENT,
2322                                              &GUID,
2323                                              &m_LIBRARYSUFFIX);
2324    }
2325  else
2326    {
2327      if (constituent.windows)
2328        {
2329          vcproj_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2330                                                  &m_PACKAGE,
2331                                                  &m_CONSTITUENT,
2332                                                  &GUID);
2333        }
2334      else
2335        {
2336          vcproj_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2337                                                      &m_PACKAGE,
2338                                                      &m_CONSTITUENT,
2339                                                      &GUID);
2340        }
2341    }
2342 
2343  for (i = 0; i < sources.size (); i++)
2344    {
2345      file = sources[i];
2346     
2347      set_full_name (full_name, file);
2348      if (full_name == "") continue;
2349     
2350      static CmtSystem::cmt_string_vector files;
2351     
2352      get_all_files (full_name, excludes, selects, files);
2353     
2354      for (int j = 0; j < files.size (); j++)
2355        {
2356          const cmt_string& name = files[j];
2357         
2358          if (name != "")
2359            {
2360              m_FULLNAME = name;
2361
2362              // Add Directory Support here
2363              // Step 1: Parse into "..\src\" "directory" "\filename.cxx"
2364
2365              // find ..\ ;
2366              src_pos = name.find('\\');
2367              // Finds ..\src\ ;
2368              dir_pos = name.find(src_pos+1, '\\') + 1;
2369              // Finds ..\src\..\astro\ ;
2370              file_pos = name.find_last_of('\\');
2371             
2372              // Debug only
2373              //printf("%40s, %i, %i, %i;\n", name src_pos, dir_pos, file_pos);
2374              // If dir_pos == file_pos, then we have ../src/filename.cxx
2375              // If dir_pos >  file_pos, then we have ../filename.cxx or something odd.
2376                           
2377              // Step 2: see if it is or is not a ../src/ directory.
2378              if ((dir_pos < file_pos) && (dir_pos > src_pos))
2379                {
2380                  new_dir = name.substr (dir_pos, file_pos-dir_pos);
2381                  new_dir.replace( "..\\", ""); // All names are relative to package/Visual,
2382                                                // so we want to ditch the prevailing ..\ ;
2383                                                // which all of them have.
2384                }
2385              else
2386                {
2387                  new_dir = "Source Files NN";
2388                }
2389
2390              // Step 3: Add directory structure to vcproj file.
2391              if (new_dir != directory) // Detects a change in directory
2392                {
2393                  directory = new_dir;
2394                  // Step 3a: Add a </Filter> when neccessary.
2395                  if (need_trailer == false)
2396                    {
2397                      // Ensure that no trailing </Filter> is placed incorrectly.
2398                      need_trailer = true;
2399                    }
2400                  else
2401                    {
2402                      vcproj_directory_trailer_fragment.wincopy (m_output_file,
2403                                                                 constituent.variables, 1,
2404                                                                 &m_PACKAGE);
2405                    }
2406
2407                  // Step 3b: Add a <Filter> when neccessary.
2408                  if ((dir_pos < file_pos) && (dir_pos > src_pos))
2409                    {
2410                      // Add <Filter Name="directory">
2411                      m_DIRNAME = new_dir;
2412                      vcproj_directory_header_fragment.wincopy (m_output_file, constituent.variables, 2,
2413                                                                &m_PACKAGE,
2414                                                                &m_DIRNAME);
2415                    }
2416                  else
2417                    {
2418                      // Ensure that no </Filter> is placed incorrectly.
2419                      // This is the case of the file being in ../src
2420                      // which requires no directory. Thus no filter start or end tag is needed.
2421
2422                      need_trailer = false;
2423                    }
2424                }
2425
2426              if (m_output_file != NULL)
2427                {
2428                  vcproj_contents_fragment.wincopy (m_output_file, constituent.variables, 2,
2429                                                    &m_PACKAGE,
2430                                                    &m_FULLNAME);
2431                }
2432            }
2433        }
2434    }
2435
2436  if (need_trailer == true)
2437    {
2438      // Add a trailing </Filter> for directory support.
2439      vcproj_directory_trailer_fragment.wincopy (m_output_file, constituent.variables, 1,
2440                                                 &m_PACKAGE);
2441    }
2442
2443  if (m_output_file != NULL)
2444    {
2445      vcproj_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
2446                                       &m_PACKAGE,
2447                                       &m_CONSTITUENT,
2448                                       &m_CONSTITUENTSUFFIX);
2449
2450      terminate ();
2451    }
2452
2453  return (0);
2454}
2455
2456MakeSetupGenerator::MakeSetupGenerator ()
2457{
2458  make_setup_header_fragment.set ("make_setup_header");
2459  make_setup_fragment.set ("make_setup");
2460}
2461
2462void MakeSetupGenerator::reset ()
2463{
2464  CmtGenerator::reset ();
2465
2466  make_setup_header_fragment.reset ();
2467  make_setup_fragment.reset ();
2468}
2469
2470void MakeSetupGenerator::build (const cmt_string& package)
2471{
2472  reset ();
2473
2474  m_PACKAGE = package;
2475
2476  cmt_string file_name = "setup.";
2477
2478  if (Cmt::build_nmake ())
2479    {
2480      file_name += "nmake";
2481    }
2482  else
2483    {
2484      file_name += "make";
2485    }
2486 
2487  cmt_string new_file_name = file_name;
2488  new_file_name += "new";
2489
2490  m_output_file = fopen (new_file_name, "wb");
2491
2492  if (m_output_file != NULL)
2493    {
2494      int number;
2495
2496      const Use::UsePtrVector& uses = Use::get_ordered_uses ();
2497
2498      const Constituent::ConstituentVector& constituents =
2499        Constituent::constituents ();
2500
2501      cmt_string temp;
2502
2503      make_setup_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2504
2505      for (number = 0; number < uses.size (); number++)
2506        {
2507          const Use* use = uses[number];
2508
2509          if (use->discarded) continue;
2510
2511          if (use->real_path != "")
2512            {
2513              temp  = use->prefix;
2514              temp += "ROOT = ";
2515              temp += use->get_full_path ();
2516
2517              fprintf (m_output_file, "%s\n", temp.c_str());
2518            }
2519        }
2520
2521      temp  = "use_requirements = ";
2522      temp += "requirements ";
2523
2524      for (number = 0; number < uses.size (); number++)
2525        {
2526          const Use* use = uses[number];
2527
2528          if (use->discarded) continue;
2529
2530          if (use->real_path != "")
2531            {
2532              temp += "$(";
2533              temp += use->prefix;
2534              temp += "ROOT)";
2535              temp += CmtSystem::file_separator ();
2536              switch (use->style)
2537                {
2538                case cmt_style:
2539                  temp += "cmt";
2540                  break;
2541                case mgr_style:
2542                  temp += "mgr";
2543                  break;
2544                }
2545              temp += CmtSystem::file_separator ();
2546              temp += "requirements ";
2547            }
2548        }
2549
2550      fprintf (m_output_file, "%s\n", temp.c_str());
2551
2552      temp  = "constituents = $(constituents)";
2553      Symbol::expand (temp);
2554
2555      fprintf (m_output_file, "%s\n", temp.c_str());
2556
2557      make_setup_fragment.copy (m_output_file, 1, &m_PACKAGE);
2558
2559      CmtSystem::close_ostream (m_output_file, new_file_name);
2560      //  fclose (m_output_file);
2561
2562      //--- Complete the operation --------------
2563
2564      commit (new_file_name);
2565    }
2566  else
2567    {
2568      CmtError::set (CmtError::file_access_error, new_file_name);
2569    }
2570
2571  /*
2572    for option in $*
2573    do
2574    case ${option} in
2575    args-tag=*)
2576    tag=${option}
2577    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2578    ;;
2579    -tag=*)
2580    tag=args${option}
2581    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2582    ;;
2583    esac
2584    done
2585
2586    if test "${tag}" = "" ; then
2587    tag=${CMTCONFIG}
2588    fi
2589
2590    build_shell_setup_files ${tag}
2591
2592    now=`date`
2593
2594  */
2595}
2596
2597ConstituentsMakefileGenerator::ConstituentsMakefileGenerator ()
2598{
2599  constituents_header_fragment.set ("constituents_header");
2600  constituents_trailer_fragment.set ("constituents_trailer");
2601  group_fragment.set ("group");
2602  constituent_fragment.set ("constituent");
2603  constituent_lock_fragment.set ("constituent_lock");
2604  check_application_header_fragment.set ("check_application_header");
2605}
2606
2607void ConstituentsMakefileGenerator::reset ()
2608{
2609  CmtGenerator::reset ();
2610  constituents_header_fragment.reset ();
2611  constituents_trailer_fragment.reset ();
2612  group_fragment.reset ();
2613  constituent_fragment.reset ();
2614  constituent_lock_fragment.reset ();
2615  check_application_header_fragment.reset ();
2616}
2617
2618//--------------------------------------------------
2619void ConstituentsMakefileGenerator::build (const cmt_string& package,
2620                                           const cmt_string& file)
2621//                                         const CmtSystem::cmt_string_vector& arguments)
2622{
2623  reset ();
2624
2625  cmt_string file_name (file);
2626    //, dir_name;
2627
2628//   if (arguments.size () > 0)
2629//     {
2630//       cmt_string arg = arguments[0];
2631//       if (arg.substr (0, 5) == "-out=")
2632//      {
2633//        arg.erase (0, 5);
2634//        file_name = arg;
2635//      }
2636//       else if (arg.substr (0, 8) == "-outdir=")
2637//      {
2638//        arg.erase (0, 8);
2639//        dir_name = arg;
2640//      }
2641//     }
2642
2643  if (file_name == "")
2644    {
2645      file_name = "constituents.";
2646
2647      //--- Build the constituents fragment -----
2648
2649      if (Cmt::build_nmake ())
2650        {
2651          file_name += "nmake";
2652        }
2653      else
2654        {
2655          file_name += "make";
2656        }
2657    }
2658
2659//   if (dir_name != "")
2660//     {
2661//       if (dir_name [dir_name.size () - 1] != CmtSystem::file_separator ())
2662//      dir_name += CmtSystem::file_separator ();
2663//       file_name = dir_name + file_name;
2664//     }
2665
2666  cmt_string save_file_name = file_name;
2667  save_file_name += "cmtsave";
2668
2669  if (CmtSystem::test_file (file_name))
2670    {
2671      rename (file_name, save_file_name);
2672    }
2673
2674  cmt_string new_file_name = file_name;
2675  new_file_name += "new";
2676
2677  m_output_file = fopen (new_file_name, "wb");
2678  if (m_output_file != NULL)
2679    {
2680      int number;
2681      const Constituent::ConstituentVector&
2682        constituents = Constituent::constituents ();
2683
2684      m_PACKAGE = package;
2685
2686      constituents_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2687
2688      m_GROUP = "all";
2689      group_fragment.copy (m_output_file, 1, &m_GROUP);
2690
2691      const Group::GroupVector& groups = Group::groups ();
2692
2693      for (number = 0; number < groups.size (); number++)
2694        {
2695          const Group& group = groups[number];
2696
2697          m_GROUP = group.name ();
2698
2699          group_fragment.copy (m_output_file, 1, &m_GROUP);
2700        }
2701     
2702      bool lock = false;
2703      Symbol* lock_command_macro = Symbol::find ("lock_command");
2704      if (lock_command_macro != 0)
2705        {
2706          cmt_string lock_command = lock_command_macro->resolve_macro_value ();
2707          if (lock_command != "")
2708            {
2709              Symbol* unlock_command_macro = Symbol::find ("unlock_command");
2710              if (unlock_command_macro != 0)
2711                {
2712                  cmt_string unlock_command = unlock_command_macro->resolve_macro_value ();
2713                  if (unlock_command != "")
2714                    {
2715                      lock = true;
2716                    }
2717                }
2718            }
2719        }
2720      for (number = 0; number < constituents.size (); number++)
2721        {
2722          const Constituent& constituent = constituents[number];
2723
2724          m_CONSTITUENT = constituent.name;
2725          m_CONSTITUENTSUFFIX = constituent.suffix;
2726
2727          m_LINE = "";
2728
2729          if (constituent.has_target_tag)
2730            {
2731              m_HASTARGETTAG = "has_target_tag";
2732            }
2733          else
2734            {
2735              m_HASTARGETTAG = "has_no_target_tag";
2736            }
2737
2738          switch (constituent.type)
2739            {
2740            case Application:
2741              m_HASDEPENDENCIES = "has_dependencies";
2742              break;
2743            case Library:
2744              m_HASDEPENDENCIES = "has_dependencies";
2745              break;
2746            case Document:
2747              m_HASDEPENDENCIES = FragmentHandle (constituent.generator).need_dependencies () ? "has_dependencies" : "has_no_dependencies" ;
2748              break;
2749            }
2750
2751          if (constituent.type == Document && lock == true)
2752            {
2753              constituent_lock_fragment.copy (m_output_file, constituent.variables,
2754                                              6,
2755                                              &m_PACKAGE,
2756                                              &m_CONSTITUENT, 
2757                                              &m_CONSTITUENTSUFFIX,
2758                                              &m_LINE,
2759                                              &m_HASDEPENDENCIES,
2760                                              &m_HASTARGETTAG);
2761            }
2762          else
2763            {
2764              constituent_fragment.copy (m_output_file, constituent.variables,
2765                                         6,
2766                                         &m_PACKAGE,
2767                                         &m_CONSTITUENT, 
2768                                         &m_CONSTITUENTSUFFIX,
2769                                         &m_LINE,
2770                                         &m_HASDEPENDENCIES,
2771                                         &m_HASTARGETTAG);
2772            }
2773
2774          if (constituent.need_check)
2775            {
2776              if (constituent.group != 0 && 
2777                  constituent.group->name () == "check")
2778                m_ISCHECKGROUP = "is_check_group";
2779              else
2780                m_ISCHECKGROUP = "is_not_check_group";
2781
2782              check_application_header_fragment.copy (m_output_file, 
2783                                                      constituent.variables, 4,
2784                                                      &m_PACKAGE,
2785                                                      &m_CONSTITUENT,
2786                                                      &m_CONSTITUENTSUFFIX,
2787                                                      &m_ISCHECKGROUP);
2788            }
2789        }
2790
2791      constituents_trailer_fragment.copy (m_output_file, 0);
2792
2793      CmtSystem::close_ostream (m_output_file, new_file_name);
2794      //  fclose (m_output_file);
2795
2796      commit (new_file_name);
2797    }
2798  else
2799    {
2800      CmtError::set (CmtError::file_access_error, new_file_name);
2801    }
2802}
2803
2804//--------------------------------------------------
2805
2806PackagesMakefileGenerator::PackagesMakefileGenerator ()
2807{
2808  m_DEPENDENCIES.set ("DEPENDENCIES");
2809  m_PACKAGEMGRPATH.set ("PACKAGEMGRPATH");
2810  m_PACKAGEFULLNAME.set ("PACKAGEFULLNAME");
2811  m_ISLOCAL.set ("ISLOCAL");
2812  m_ISINCLUDED.set ("ISINCLUDED");
2813
2814  packages_header_fragment.set ("packages_header");
2815  packages_trailer_fragment.set ("packages_trailer");
2816  package_fragment.set ("package");
2817}
2818
2819void PackagesMakefileGenerator::reset ()
2820{
2821  CmtGenerator::reset ();
2822  m_DEPENDENCIES = "";
2823  m_PACKAGEMGRPATH = "";
2824  m_PACKAGEFULLNAME = "";
2825  m_ISLOCAL = "";
2826  m_ISINCLUDED = "";
2827
2828  packages_header_fragment.reset ();
2829  packages_trailer_fragment.reset ();
2830  package_fragment.reset ();
2831}
2832
2833//--------------------------------------------------
2834void PackagesMakefileGenerator::build (const cmt_string& package,
2835                                       const cmt_string& file)
2836{
2837  reset ();
2838
2839  cmt_string file_name (file);
2840  if (file_name == "")
2841    {
2842      file_name = "packages.";
2843
2844      if (Cmt::build_nmake ())
2845        {
2846          file_name += "nmake";
2847        }
2848      else
2849        {
2850          file_name += "make";
2851        }
2852    }
2853
2854  cmt_string save_file_name = file_name;
2855  save_file_name += "cmtsave";
2856
2857  if (CmtSystem::test_file (file_name))
2858    {
2859      rename (file_name, save_file_name);
2860    }
2861
2862  cmt_string new_file_name = file_name;
2863  new_file_name += "new";
2864
2865  m_output_file = fopen (new_file_name, "wb");
2866  if (m_output_file != NULL)
2867    {
2868      m_PACKAGE = package;
2869
2870      if (!packages_header_fragment.copy (m_output_file, 1, &m_PACKAGE)) return;
2871
2872      const Project* p_cur (Project::get_current ());
2873      Use::UsePtrVector uses (Use::get_ordered_uses ());
2874      uses.push_back (&Use::current ());
2875
2876      Project::ConstProjectPtrVector path_exclusions;
2877      Project::fill_exclusion (path_exclusions);
2878
2879      cmt_string temp;
2880      for (int i = uses.size () - 1; i >= 0; i--)
2881        {
2882          Use* use = uses[i];
2883
2884          if (use->discarded) continue;
2885          if (use->m_hidden) continue;
2886          if (!use->located ()) continue;
2887          if (use->get_package ()->is_cmt ()) continue;
2888
2889          const Project* up = use->get_project ();
2890
2891          m_ISLOCAL = "is_not_local";
2892          if (p_cur)
2893            {
2894              if (up)
2895                {
2896                  if (up == p_cur)
2897                    {
2898                      m_ISLOCAL = "is_local";
2899                    }
2900                }
2901              else
2902                {
2903                  if (use->get_realpath ().find (p_cur->get_cmtpath_real ()) == 0)
2904                    {
2905                      m_ISLOCAL = "is_local";
2906                    }
2907                }
2908            }
2909          else if (use == &Use::current ())
2910            {
2911              m_ISLOCAL = "is_local";
2912            }
2913
2914          m_ISINCLUDED = "is_included";
2915          for (int j = 0; j < path_exclusions.size (); j++)
2916            {
2917              const Project* sp = path_exclusions[j];
2918              if (up)
2919                {
2920                  if (up == sp)
2921                    {
2922                      m_ISINCLUDED = "is_not_included";
2923                    }
2924                }
2925              else
2926                {
2927                  if (use->get_realpath ().find (sp->get_cmtpath_real ()) == 0)
2928                    {
2929                      m_ISINCLUDED = "is_not_included";
2930                    }
2931                }
2932            }
2933
2934          temp = use->get_full_path ();
2935          switch (use->style)
2936            {
2937            case cmt_style:
2938              temp += CmtSystem::file_separator ();
2939              temp += "cmt";
2940              break;
2941            case mgr_style:
2942              temp += CmtSystem::file_separator ();
2943              temp += "mgr";
2944              break;
2945            default:
2946              break;
2947            }
2948#ifdef WIN32
2949          temp += " ";
2950#endif
2951          m_PACKAGEMGRPATH = temp;
2952
2953          temp = "";
2954          if (Symbol* s = Symbol::find (use->get_package_name () + "_offset"))
2955            {
2956              cmt_string o = s->build_macro_value ();
2957              if (o != "")
2958                {
2959                  temp += o;
2960                  temp += CmtSystem::file_separator ();
2961                }
2962            }
2963          else
2964            {
2965              CmtMessage::warning
2966                (CmtError::get_error_name (CmtError::symbol_not_found)
2967                 + ": macro " + use->get_package_name () + "_offset");
2968            }
2969          temp += use->get_package_name ();
2970          temp.replace_all (CmtSystem::file_separator (), "_");
2971#ifdef WIN32
2972          temp += " ";
2973#endif
2974          m_PACKAGEFULLNAME = temp;
2975
2976          m_PACKAGE = use->get_package_name ();
2977          m_PACKAGEPREFIX = use->prefix;
2978
2979          Use::UsePtrVector subuses;
2980          for (int i = 0; i < use->sub_uses.size (); i++)
2981            {
2982              if (use->sub_uses[i]->m_index >= 0 && !use->sub_uses[i]->discarded)
2983                {
2984                  if (use->sub_uses[i]->m_hidden) continue;
2985                  subuses.push_back (use->sub_uses[i]);
2986                }
2987              else
2988                {
2989                  Use* au (Use::find_valid (use->sub_uses[i]->get_package_name ()));
2990                  if (au)
2991                    {
2992                      subuses.push_back (au);
2993                    }
2994                }
2995            }
2996          m_DEPENDENCIES = "";
2997          for (int i = 0; i < subuses.size (); i++)
2998            {
2999              if (i != 0)
3000                {
3001                  m_DEPENDENCIES += " " + subuses[i]->get_package_name ();
3002                }
3003              else
3004                {
3005                  m_DEPENDENCIES += subuses[i]->get_package_name ();
3006                }
3007            }
3008
3009          if (!package_fragment.copy (m_output_file, 7,
3010                                      &m_PACKAGE, &m_PACKAGEPREFIX,
3011                                      &m_DEPENDENCIES,
3012                                      &m_PACKAGEMGRPATH, &m_PACKAGEFULLNAME,
3013                                      &m_ISLOCAL, &m_ISINCLUDED)) return;
3014        }
3015
3016      if (Symbol* s = Symbol::find ("CMTINSTALLAREA"))
3017        {
3018          cmt_string o = s->build_macro_value ();
3019          Symbol::expand (o);
3020          if (o != "")
3021            {
3022              temp  = "CMTINSTALLAREA=";
3023              temp += o;
3024#ifdef WIN32
3025              temp += " ";
3026#endif
3027              fprintf (m_output_file, "%s\n", temp.c_str());
3028            }
3029        }
3030
3031      if (!packages_trailer_fragment.copy (m_output_file, 0)) return;
3032
3033      CmtSystem::close_ostream (m_output_file, new_file_name);
3034
3035      commit (new_file_name);
3036    }
3037  else
3038    {
3039      CmtError::set (CmtError::file_access_error, new_file_name);
3040    }
3041}
3042
3043//--------------------------------------------------
3044
3045/**
3046   With this Awk filter, we analyze an existing dependency file.
3047   We get the source name in each line
3048   The list of sources is maintained in m_sources
3049   A source is stored in the form <name>_<suffix> (instead of <name>.<suffix>)
3050*/
3051class DependencyFilter : public Awk
3052{
3053public:
3054  DependencyFilter ()
3055  {
3056  }
3057
3058  void begin ()
3059  {
3060    m_sources = "";
3061  }
3062
3063  void filter (const cmt_string& line)
3064  {
3065    int pos = line.find ("_dependencies = ");
3066    if (pos == cmt_string::npos) return;
3067
3068    cmt_string s = line;
3069    s.erase (pos);
3070
3071    m_sources += " ";
3072    m_sources += s;
3073    m_sources += " ";
3074
3075    //pos = s.find_last_of ("_");
3076    //if (pos != cmt_string::npos) s[pos] = "."
3077  }
3078
3079  void add_source (const cmt_string& file_name)
3080  {
3081    static cmt_string suffix;
3082    static cmt_string name;
3083
3084    CmtSystem::get_dot_suffix (file_name, suffix);
3085    CmtSystem::basename (file_name, suffix, name);
3086    CmtSystem::get_suffix (file_name, suffix);
3087
3088    cmt_string s = " ";
3089    s += name;
3090    s += "_";
3091    s += suffix;
3092    s += " ";
3093
3094    if (m_sources.find (s) == cmt_string::npos)
3095      {
3096        m_sources += s;
3097      }       
3098  }
3099
3100  bool has_source (const cmt_string& file_name) const
3101  {
3102    static cmt_string suffix;
3103    static cmt_string name;
3104
3105    CmtSystem::get_dot_suffix (file_name, suffix);
3106    CmtSystem::basename (file_name, suffix, name);
3107    CmtSystem::get_suffix (file_name, suffix);
3108
3109    cmt_string s = " ";
3110    s += name;
3111    s += "_";
3112    s += suffix;
3113    s += " ";
3114
3115    if (m_sources.find (s) == cmt_string::npos)
3116      {
3117        return (false);
3118      }
3119    else
3120      {
3121        return (true);
3122      }
3123  }
3124
3125  cmt_string& get_sources ()
3126  {
3127    return (m_sources);
3128  }
3129
3130private:
3131  cmt_string m_sources;
3132};
3133
3134//--------------------------------------------------
3135void DependencyGenerator::reset ()
3136{
3137  CmtGenerator::reset ();
3138  m_deps_builder.clear ();
3139  m_stamps = true;
3140  m_name = "cmt_unnamed";
3141}
3142
3143//--------------------------------------------------
3144void DependencyGenerator::prepare_includes ()
3145{
3146  cmt_string path;
3147  cmt_string substitution;
3148
3149  Use* use = &Use::current ();
3150
3151  //  m_deps_builder.clear ();
3152
3153  if (use->include_path != "none")
3154    {
3155      if (use->include_path == "")
3156        {
3157          m_deps_builder.add (incdir, "$(src)");
3158        }
3159      else
3160        {
3161          substitution = use->include_path;
3162         
3163          path = substitution;
3164          Symbol::expand (path);
3165         
3166          CmtSystem::reduce_file_separators (path);
3167
3168          m_deps_builder.add (path, substitution);
3169        }
3170    }
3171
3172  m_deps_builder.add_includes (*use);
3173
3174  Use::UsePtrVector& uses = Use::get_ordered_uses ();
3175
3176  if (uses.size () > 0)
3177    {
3178      int number;
3179
3180      for (number = 0; number < uses.size (); number++)
3181        {
3182          use = uses[number];
3183          if (use->discarded) continue;
3184
3185          if (use->real_path != "")
3186            {
3187              if (use->include_path != "none")
3188                {
3189                  if (use->include_path == "")
3190                    {
3191                      use->get_full_path (path);
3192                      path += CmtSystem::file_separator ();
3193                      path += "src";
3194
3195                      substitution = "$(";
3196                      substitution += use->prefix;
3197                      substitution += "ROOT)";
3198                      substitution += CmtSystem::file_separator ();
3199                      substitution += "src";
3200                      substitution += CmtSystem::file_separator ();
3201                    }
3202                  else
3203                    {
3204                      substitution = use->include_path;
3205
3206                      path = substitution;
3207                      Symbol::expand (path);
3208
3209                      CmtSystem::reduce_file_separators (path);
3210                    }
3211
3212                  m_deps_builder.add (path, substitution);
3213                }
3214
3215              m_deps_builder.add_includes (*use);
3216            }
3217        }
3218    }
3219}
3220
3221//--------------------------------------------------
3222void DependencyGenerator::prepare_header_file_filters ()
3223{
3224  const Use* current_use = &Use::current ();
3225  Use::UsePtrVector uses (Use::get_ordered_uses ());
3226  uses.push_back (&Use::current ());
3227  bool current_only (true);
3228  for (int i = uses.size () - 1; i >= 0; i--)
3229    {
3230      const Use* use = uses[i];
3231      //cerr << "prepare_header_file_filters(0)> " << use->get_package_name () << "[" << use->get_index () << "]\n";
3232      if (use->discarded) continue;
3233      if (use->m_hidden) continue;
3234      if (!use->located ()) continue;
3235
3236      if (current_only && use != current_use)
3237        current_only = false;
3238
3239      cmt_string package_name = use->get_package_name ();
3240      if (package_name == "CMT") continue;
3241
3242      const Symbol* filter_macro = Symbol::find (package_name + "_header_file_filter");
3243      if (filter_macro == 0) continue;
3244      const cmt_string filter_expr (filter_macro->resolve_macro_value ());
3245      if (filter_expr.size () == 0) continue;
3246
3247      const Symbol* stamp_macro = Symbol::find (package_name + "_header_file_stamp");
3248      cmt_string stamp;
3249      if (stamp_macro != 0)
3250        {
3251          stamp = stamp_macro->resolve_macro_value ();
3252        }
3253      else
3254        {
3255          use->get_full_path (stamp);
3256          switch (use->style)
3257            {
3258            case cmt_style:
3259              stamp += CmtSystem::file_separator ();
3260              stamp += "cmt";
3261              break;
3262            case mgr_style:
3263              stamp += CmtSystem::file_separator ();
3264              stamp += "mgr";
3265              break;
3266            }
3267          stamp += CmtSystem::file_separator ();
3268          stamp += "cmt_header_file.stamp";
3269          //stamp += "cmt_all_headers.stamp";
3270          //<package>/cmt/cmt_all_headers.stamp
3271        }
3272      if (!CmtSystem::test_file (stamp)) continue;
3273
3274      //cerr << "0: adding filter: " << use->get_package_name () << "[" << use->get_index () << "]\n";
3275      cmt_regexp* filter = new cmt_regexp (filter_expr);
3276      //cmt_regexp* filter = new cmt_regexp (filter_macro->resolve_macro_value ());
3277      assert (filter != 0);
3278
3279      m_deps_builder.add_header_filter (use, filter, stamp);
3280    }
3281
3282  if (current_only)
3283    { // we are most likely reading dependencies[_CONSTITUENT].in without CMT
3284      for (int number = 0; number < Symbol::symbol_number (); number++)
3285        {
3286          const Symbol& symbol = Symbol::symbol (number);
3287          if (symbol.type != Symbol::SymbolMacro) continue;
3288          int r = symbol.name.find_last_of ("_header_file_filter");
3289          if (r == cmt_string::npos ||
3290              (r + 19) != symbol.name.size () ||
3291              r == 0) continue;
3292          const cmt_string filter_expr (symbol.resolve_macro_value ());
3293          if (filter_expr.size () == 0) continue;
3294
3295          cmt_string package_name = symbol.name.substr(0, r);
3296          const Use* use = Use::find (package_name);
3297          if (use == current_use) continue;
3298          if (0 != use && use->discarded) continue;
3299          if (0 != use && use->m_hidden) continue;
3300          if (0 != use && !use->located ()) continue;
3301         
3302          //Symbol* filter_macro = Symbol::find (package_name + "_header_file_filter");
3303          //if (filter_macro == 0) continue;
3304         
3305          const Symbol* stamp_macro = Symbol::find (package_name + "_header_file_stamp");
3306          cmt_string stamp;
3307          if (stamp_macro != 0)
3308            {
3309              stamp = stamp_macro->resolve_macro_value ();
3310            }
3311          else if (0 != use)
3312            {
3313              use->get_full_path (stamp);
3314              switch (use->style)
3315                {
3316                case cmt_style:
3317                  stamp += CmtSystem::file_separator ();
3318                  stamp += "cmt";
3319                  break;
3320                case mgr_style:
3321                  stamp += CmtSystem::file_separator ();
3322                  stamp += "mgr";
3323                  break;
3324                }
3325              stamp += CmtSystem::file_separator ();
3326              stamp += "cmt_header_file.stamp";
3327            }
3328          if (!CmtSystem::test_file (stamp)) continue;
3329         
3330          //cerr << "1: adding filter: " << package_name << "\n";
3331          cmt_regexp* filter = new cmt_regexp (filter_expr);
3332          //cmt_regexp* filter = new cmt_regexp (symbol.resolve_macro_value ());
3333          assert (filter != 0);
3334         
3335          m_deps_builder.add_header_filter (use, filter, stamp);
3336        }
3337    }
3338}
3339
3340//--------------------------------------------------
3341void DependencyGenerator::build (const CmtSystem::cmt_string_vector& arguments)
3342{
3343  reset ();
3344
3345  //
3346  // Parse arguments first
3347  //
3348  CmtSystem::cmt_string_vector cli_input, all;
3349  bool all_sources = false;
3350  bool config_files (false);
3351  bool start_all (false);
3352
3353  for (int i = 0; i < arguments.size (); i++)
3354    {
3355      cmt_string file_name = arguments[i];
3356
3357      //cerr << "i: " << i << " file_name=" << file_name << endl;
3358
3359      if (file_name.substr (0, 5) == "-out=" ||
3360          file_name.substr (0, 5) == "-out:" ||
3361          file_name.substr (0, 5) == "/out:" ||
3362          file_name.substr (0, 5) == "/out=")
3363        {
3364          file_name.erase (0, 5);
3365          m_output_file_name = file_name;
3366        }
3367      else if (file_name.substr (0, 6) == "-name=" ||
3368               file_name.substr (0, 6) == "-name:" ||
3369               file_name.substr (0, 6) == "/name:" ||
3370               file_name.substr (0, 6) == "/name=")
3371        {
3372          file_name.erase (0, 6);
3373          m_name = file_name;
3374        }
3375      else if (file_name == "-all_sources" ||
3376               file_name == "/all_sources") 
3377        {
3378          all_sources = true;
3379        }
3380      else if (file_name == "-no_stamps" ||
3381               file_name == "/no_stamps") 
3382        {
3383          m_stamps = false;
3384        }
3385      else if (file_name.substr (0, 2) == "-I" ||
3386               file_name.substr (0, 2) == "/I")
3387        {
3388          file_name.erase (0, 2);
3389          //cerr << "include: " << file_name << endl;
3390          m_deps_builder.add (file_name, file_name);
3391        }
3392      else if (file_name  == "-start_all" ||
3393               file_name  == "/start_all")
3394        {
3395          if (start_all)
3396            {
3397              CmtError::set(CmtError::syntax_error,
3398                            "Unexpected option " + file_name);
3399              return;
3400            }
3401          start_all = true;
3402        }
3403      else if (file_name == "-end_all" ||
3404               file_name == "/end_all")
3405        {
3406          if (!start_all)
3407            {
3408              CmtMessage::warning
3409                (CmtError::get_error_name (CmtError::syntax_error)
3410                 + ": Unexpected option " + file_name);
3411            }
3412          start_all = false;
3413        }
3414      else if (file_name.substr (0, 1) == "-"
3415#ifdef WIN32
3416               || file_name.substr (0, 1) == "/"
3417#endif
3418               )
3419        {
3420          if (CmtMessage::active (Verbose))
3421            CmtMessage::warning
3422              (CmtError::get_error_name (CmtError::warning)
3423               + ": Unknown option " + file_name);
3424        }
3425      else if (file_name.substr (file_name.size () - 12) == "requirements" ||
3426               file_name.substr (file_name.size () - 5) == ".make" ||
3427               file_name.substr (file_name.size () - 3) == ".mk" ||
3428               file_name.substr (file_name.size () - 6) == ".nmake" ||
3429               file_name.substr (file_name.size () - 3) == ".in" ||
3430               file_name.substr (file_name.size () - 6) == ".stamp")
3431        {
3432          // Configuration changed,
3433          // want to rebuild dependencies from scratch
3434          if (!config_files) config_files = true;
3435          if (!all_sources) all_sources = true;
3436        }
3437      else if (start_all)
3438        {
3439          all.push_back (file_name);
3440        }
3441      else
3442        {
3443          cli_input.push_back (file_name);
3444        }
3445    }
3446 
3447  if (start_all)
3448    CmtMessage::warning
3449      (CmtError::get_error_name (CmtError::syntax_error)
3450       + ": Missing option -end_all");
3451
3452  //cerr << "m_name: " << m_name << endl;
3453  /*
3454  if (m_name.size () == 0)
3455    {
3456      CmtError::set(CmtError::syntax_error,
3457                    "Name missing as first argument");
3458      return;
3459    }
3460  */
3461  //cerr << "config_files: " << config_files << endl;
3462
3463  if (0 != m_name.size ())
3464    m_constituent = Constituent::find (m_name);
3465
3466  if (!config_files && 0 == cli_input.size () &&
3467      0 == all.size () && 0 == m_constituent)
3468    {
3469      CmtError::set(CmtError::syntax_error,
3470                    m_name + ": Files arguments missing");
3471      return;
3472    }
3473  /*
3474  cerr << "cli_input:";
3475  for (int i = 0; i < cli_input.size (); i++)
3476    cerr << " " << cli_input[i];
3477  cerr << "\n";
3478
3479  cerr << "all:";
3480  for (int i = 0; i < all.size (); i++)
3481    cerr << " " << all[i];
3482  cerr << "\n";
3483  */
3484  prepare_includes ();
3485  prepare_header_file_filters ();
3486
3487  //
3488  // Now prepare the output file names
3489  //
3490  cmt_string branch = CmtSystem::current_branch ();
3491
3492  if ((branch == "mgr") || (branch == "cmt"))
3493    {
3494      Use& current_use = Use::current ();
3495
3496      Package* p = current_use.get_package ();
3497
3498      if (p->is_cmt ())
3499        {
3500          //          m_bin = "../";
3501          m_bin = "..";
3502          m_bin += CmtSystem::file_separator ();
3503          m_bin += CmtSystem::getenv ("CMTBIN");
3504          m_bin += CmtSystem::file_separator ();
3505        }
3506      else if (m_output_file_name != "")
3507        {
3508          CmtSystem::dirname (m_output_file_name, m_bin);
3509          if (m_bin == "")
3510            {
3511              m_bin = ".";
3512            }
3513          m_bin += CmtSystem::file_separator ();
3514        }
3515      else
3516        {
3517          m_bin = "${bin}";
3518        }
3519
3520      Symbol::expand (m_bin);
3521
3522      //cerr << "m_output_file_name=" << m_output_file_name << endl;
3523      //cerr << "current_tag=" << Cmt::current_tag << endl;
3524    }
3525  else
3526    {
3527      m_bin = ".";
3528      m_bin += CmtSystem::file_separator ();
3529    }
3530
3531  if (m_output_file_name == "")
3532    {
3533      m_output_file_name = m_bin;
3534      m_output_file_name += m_name;
3535      m_output_file_name += "_";
3536      m_output_file_name += "dependencies.";
3537      if (Cmt::build_nmake ())
3538        {
3539          m_output_file_name += "nmake";
3540        }
3541      else
3542        {
3543          m_output_file_name += "make";
3544        }
3545    }
3546
3547  //-------------------------------------------------------------------------------
3548  //
3549  // For Makefile, we need to select, from cli_input, source files only,
3550  // there may be dependencies of source files (typically, header files) as well
3551  //
3552  cmt_string dependencies;
3553  if (!all_sources)
3554    {
3555      // want to validate cli_input against
3556      //   either
3557      // o all cli sources
3558      //   or
3559      // o m_constituent sources
3560      if (int n = set_source_files (all))
3561        {
3562          if (0 == validate (cli_input))
3563            {
3564              // cli_input contains source files ONLY
3565              // calculate dependencies for them ONLY
3566              if (CmtSystem::test_file (m_output_file_name))
3567                {
3568                  if (!dependencies.read (m_output_file_name))
3569                    {
3570                      CmtError::set (CmtError::file_access_error, m_output_file_name);
3571                      return;
3572                    }
3573                }
3574              fill_dependencies (dependencies, cli_input);
3575            }
3576          else
3577            {
3578              all_sources = true;
3579              // calculate dependencies for
3580              // all cli sources
3581              // or
3582              // m_constituent sources
3583              fill_dependencies (dependencies);
3584            }
3585        }
3586      else
3587        {
3588          // calculate dependencies for all we have
3589          fill_dependencies (dependencies, cli_input);
3590        }
3591      /*
3592      if (0 != all.size ())
3593        {
3594          // o all cli sources
3595          int n_invalid = 0;
3596          for (int i = 0; i < cli_input.size (); i++)
3597            {
3598              bool valid = false;
3599              for (int j = 0; j < all.size (); j++)
3600                if (cli_input[i] == all[j])
3601                  {
3602                    valid = true;
3603                    break;
3604                  }
3605              if (!valid)
3606                {
3607                  n_invalid += 1;
3608                  break;
3609                }
3610            }
3611          if (0 == n_invalid)
3612            {
3613              // cli_input contains source files ONLY
3614              // calculate dependencies for them ONLY
3615              if (CmtSystem::test_file (m_output_file_name))
3616                {
3617                  if (!dependencies.read (m_output_file_name))
3618                    {
3619                      CmtError::set (CmtError::file_access_error, m_output_file_name);
3620                      return;
3621                    }
3622                }
3623              fill_dependencies (dependencies, cli_input);
3624            }
3625          else
3626            {
3627              all_sources = true;
3628              // calculate dependencies for all (all cli sources)
3629              fill_dependencies (dependencies, all);
3630            }
3631        }
3632      else // 0 == all.size ()
3633        {
3634          //      set_source_files ();
3635          if (int n = set_source_files ())
3636            //    if (0 != m_source_files.size ())
3637            {
3638              // o m_constituent sources
3639              int n_invalid = 0;
3640              for (int i = 0; i < cli_input.size (); i++)
3641                {
3642                  bool valid = false;
3643                  for (int j = 0; j < n; j++)
3644                    if (cli_input[i] == m_source_files[j].name ())
3645                      {
3646                        valid = true;
3647                        break;
3648                      }
3649                  if (!valid)
3650                    {
3651                      n_invalid += 1;
3652                      break;
3653                    }
3654                }
3655              if (0 == n_invalid)
3656                {
3657                  // cli_input contains source files ONLY
3658                  // calculate dependencies for them ONLY
3659                  if (CmtSystem::test_file (m_output_file_name))
3660                    {
3661                      if (!dependencies.read (m_output_file_name))
3662                        {
3663                          CmtError::set (CmtError::file_access_error, m_output_file_name);
3664                          return;
3665                        }
3666                    }
3667                  fill_dependencies (dependencies, cli_input);
3668                }
3669              else
3670                {
3671                  all_sources = true;
3672                  // calculate dependencies for m_source_files
3673                  // (m_constituent sources)
3674                  fill_dependencies (dependencies);
3675                }
3676            }
3677          else // 0 == m_source_files.size ())
3678            {
3679              // no source files to validate against
3680              fill_dependencies (dependencies, cli_input);
3681            }
3682        }
3683      */
3684    }
3685  else // all_sources = true
3686    {
3687      if (int n = set_source_files (all))
3688        {
3689          // calculate dependencies for m_source_files
3690          //   either
3691          // o all cli sources
3692          //   or
3693          // o m_constituent sources
3694          //   if any existing
3695          fill_dependencies (dependencies);
3696        }
3697      else
3698        {
3699          // calculate dependencies for all we have
3700          fill_dependencies (dependencies, cli_input);
3701        }
3702      /*
3703      if (0 != all.size ())
3704        {
3705          // calculate dependencies for all (all cli sources)
3706          fill_dependencies (dependencies, all);
3707        }
3708      else
3709        {
3710          if (int n = set_source_files ())
3711            {
3712              // calculate dependencies for m_source_files (m_constituent sources)
3713              fill_dependencies (dependencies);
3714            }
3715          else
3716            {
3717              // calculate dependencies for all we have
3718              fill_dependencies (dependencies, cli_input);
3719            }
3720        }
3721      */
3722    }
3723
3724  if (CmtError::has_pending_error ())
3725    {
3726      if (CmtError::get_last_error_code () == CmtError::path_not_found ||
3727          CmtError::get_last_error_code () == CmtError::file_access_error ||
3728          CmtError::get_last_error_code () == CmtError::execution_failed)
3729        return;
3730    }
3731  //-------------------------------------------------------------------------------
3732
3733  FILE* f = fopen (m_output_file_name.c_str (), "wb");
3734
3735  if (f != 0)
3736    {
3737      dependencies.write (f);
3738      CmtSystem::close_ostream (f, m_output_file_name);
3739    }
3740  else
3741    {
3742      CmtError::set (CmtError::file_access_error, m_output_file_name);
3743    }
3744
3745//  m_deps_builder.clear ();
3746}
3747
3748//--------------------------------------------------
3749//  o text contains lines with a pattern like :
3750//      key = value
3751//  o line follows the same pattern
3752//
3753//  This function
3754//    o if the key found in <line> is found in <text>, removes the first line in <text> with the key, if any
3755//    o appends <line> to <text>
3756//--------------------------------------------------
3757void DependencyGenerator::add_line_to_text (const cmt_string& line, cmt_string& text) const
3758{
3759  static const cmt_string empty;
3760
3761  int pos = line.find (" = ");
3762  if (pos != cmt_string::npos)
3763    {
3764      static cmt_string key;
3765      line.substr (0, pos + 3, key);
3766      pos = text.find (key);
3767      if (pos != cmt_string::npos)
3768        {
3769          // The key in line exists in text.
3770          // Now check if the key is exactly the same.
3771
3772          if ((pos == 0) || (text[pos -1] == '\n'))
3773            {
3774              // The key is either in the first line or
3775              // exactly matches '^key = ...'
3776
3777              int nl = text.find (pos, "\n");
3778              if (nl != cmt_string::npos)
3779                {
3780                  static cmt_string old;
3781                  text.substr (pos, nl - pos + 1, old);
3782                  text.replace (old, empty);
3783                }
3784              else
3785                {
3786                  text.erase (pos);
3787                }
3788            }
3789        }
3790    }
3791  if (line != "")
3792    {
3793      text += line;
3794      text += "\n";
3795    }
3796}
3797
3798//--------------------------------------------------
3799cmt_string DependencyGenerator::build (const cmt_string& file_name)
3800{
3801  Log;
3802
3803  //  const Constituent& constituent = *m_constituent;
3804
3805  static cmt_string full_name;
3806  static cmt_string suffix;
3807  static cmt_string name;
3808  static cmt_string line;
3809
3810  full_name = "";
3811  line = "";
3812
3813  /*
3814  if (!CmtSystem::absolute_path (file_name))
3815    {
3816      full_name = srcdir;
3817    }
3818  */
3819
3820  full_name += file_name;
3821
3822  CmtSystem::get_dot_suffix (full_name, suffix);
3823  CmtSystem::basename (full_name, suffix, name);
3824  CmtSystem::get_suffix (full_name, suffix);
3825
3826  //  if (name == "requirements") return (line);
3827
3828  const CmtSystem::cmt_string_vector& deps = m_deps_builder.run (full_name, m_name);
3829  if (CmtError::has_pending_error ())
3830    {
3831      return line;
3832    }
3833  //      CmtError::set (CmtError::execution_failed, preprocessor, status);
3834  //      CmtError::set (CmtError::file_access_error, header_file_path);
3835  //      CmtError::set (CmtError::path_not_found, name);
3836
3837  line  = name;
3838  line += "_";
3839  line += suffix;
3840  line += "_dependencies = ";
3841
3842  filter_path (full_name);
3843
3844#ifdef WIN32
3845  static const char quote = '\"';
3846#else
3847  static const char quote = ' ';
3848#endif
3849
3850  line += quote;
3851  line += full_name;
3852  line += quote;
3853
3854  for (int j = 0; j < deps.size (); j++)
3855    {
3856      cmt_string d = deps[j];
3857
3858      log << "dep line = " << d << log_endl;
3859
3860      filter_path (d);
3861
3862      log << "filtered dep line = " << d << log_endl;
3863
3864      line += " ";
3865      line += quote;
3866      line += d;
3867      line += quote;
3868    }
3869
3870  Symbol::expand (line);
3871
3872  if (m_stamps)
3873    {
3874      cmt_string stamp_output_base = m_name;
3875      //      cmt_string stamp_output_base = constituent.name;
3876      stamp_output_base += "_deps";
3877
3878      cmt_string stamp_output = m_bin;
3879      stamp_output += stamp_output_base;
3880
3881      if (!CmtSystem::mkdir (stamp_output))
3882        {
3883          CmtError::set (CmtError::file_access_error, 
3884                         + "Cannot create directory " + stamp_output
3885                         + " for " + m_name);
3886          return line;
3887        }
3888
3889      stamp_output_base += CmtSystem::file_separator ();
3890      stamp_output_base += name;
3891      stamp_output_base += "_";
3892      stamp_output_base += suffix;
3893      stamp_output_base += ".stamp";
3894
3895      stamp_output = m_bin;
3896      stamp_output += stamp_output_base;
3897     
3898      line += " $(bin)";
3899      line += stamp_output_base;
3900     
3901      cmt_string old_stamp;
3902     
3903      if (CmtSystem::test_file (stamp_output))
3904        {
3905          if (!old_stamp.read (stamp_output))
3906            {
3907              CmtError::set (CmtError::file_access_error, stamp_output);
3908              return line;
3909            }
3910          //      old_stamp.read (stamp_output);
3911        }
3912
3913      if (line != old_stamp.substr(0, old_stamp.size () - 1))
3914        {
3915          if (!(line + "\n").write (stamp_output))
3916            {
3917              CmtError::set (CmtError::file_access_error, stamp_output);
3918              return line;
3919            }
3920          //      (line + "\n").write (stamp_output);
3921        }
3922    }
3923
3924  return (line);
3925}
3926
3927//--------------------------------------------------
3928int DependencyGenerator::fill_dependencies (cmt_string& dependencies)
3929{
3930  CmtSystem::cmt_string_vector sources;
3931  for (int i = 0; i < m_source_files.size (); i++)
3932    {
3933      const SourceFile& file = m_source_files[i];
3934      sources.push_back (file.name ());
3935    }
3936  return fill_dependencies (dependencies, sources);
3937}
3938
3939//--------------------------------------------------
3940int DependencyGenerator::fill_dependencies (cmt_string& dependencies,
3941                                            const CmtSystem::cmt_string_vector& sources)
3942{
3943  int retval (0);
3944  cmt_string file_name;
3945  cmt_string compressed_name;
3946
3947  for (int i = 0; i < sources.size (); i++)
3948    {
3949      file_name = sources[i];
3950      //set_full_name (full_name, file_name);
3951      CmtSystem::reduce_file_separators (file_name);
3952      if (file_name == "") continue;
3953      CmtSystem::compress_path (file_name, compressed_name);
3954      file_name = compressed_name;
3955      //cerr << "file_name: " << file_name << endl;     
3956      if (file_name == "") continue;
3957
3958      const cmt_string& line = build (file_name);
3959      if (CmtError::has_pending_error ())
3960        {
3961          //      if (CmtError::get_last_error_code () == CmtError::file_access_error)
3962          return -1;
3963        }
3964     
3965      //cerr << "line: " << line << endl;     
3966      add_line_to_text (line, dependencies);
3967      //cerr << "dependencies: " << dependencies << endl;     
3968    }
3969
3970  return retval;
3971}
3972
3973//--------------------------------------------------
3974int DependencyGenerator::set_source_files (const CmtSystem::cmt_string_vector& files)
3975{
3976  m_source_files.clear ();
3977
3978  for (int j = 0; j < files.size (); j++)
3979    {
3980      const cmt_string& name = files[j];
3981      if (name == "") continue;
3982
3983      bool included = false;
3984      for (int k = m_source_files.size () - 1; k >= 0; k--)
3985        if (m_source_files[k].name () == name)
3986          {
3987            included = true;
3988            break;
3989          }
3990      if (included) continue;
3991     
3992      SourceFile& source = m_source_files.add ();
3993      source.set (name, Language::null (), "");
3994    }
3995     
3996  if (m_source_files.size ()) return m_source_files.size ();
3997  else return set_source_files ();
3998}
3999
4000//--------------------------------------------------
4001int DependencyGenerator::set_source_files ()
4002{
4003  if (0 == m_constituent && 0 != m_name.size ())
4004    m_constituent = Constituent::find (m_name);
4005  if (0 == m_constituent) return 0;
4006
4007  m_source_files.clear ();
4008
4009  const CmtSystem::cmt_string_vector& sources = m_constituent->modules;
4010  const cmt_vector<cmt_regexp>& excludes = m_constituent->exclude_exprs;
4011  const cmt_vector<cmt_regexp>& selects = m_constituent->select_exprs;
4012
4013  cmt_string file_name, full_name;
4014  cmt_string compressed_name;
4015  cmt_string visited, token;
4016
4017  for (int i = 0; i < sources.size (); i++)
4018    {
4019      file_name = sources[i];
4020      set_full_name (full_name, file_name);
4021      if (full_name == "") continue;
4022     
4023      CmtSystem::compress_path (full_name, compressed_name);
4024      full_name = compressed_name;
4025     
4026      static CmtSystem::cmt_string_vector files;
4027     
4028      get_all_files (full_name, excludes, selects, files);
4029     
4030      for (int j = 0; j < files.size (); j++)
4031        {
4032          const cmt_string& name = files[j];
4033             
4034          if (name == "") continue;
4035         
4036          cmt_string suffix;
4037          CmtSystem::get_suffix (name, suffix);
4038          Language& language = Language::find_with_suffix (suffix);
4039
4040          if ((m_constituent->type == Application || m_constituent->type == Library)
4041              && language != Language::null () && language.native_dependencies ())
4042            continue;
4043
4044          bool included = false;
4045          for (int k = m_source_files.size () - 1; k >= 0; k--)
4046            if (m_source_files[k].name () == name)
4047              {
4048                included = true;
4049                break;
4050              }
4051          if (included) continue;
4052         
4053          SourceFile& source = m_source_files.add ();
4054          source.set (name, language, "");
4055        }
4056    }
4057  return m_source_files.size ();
4058}
4059
4060//--------------------------------------------------
4061/**
4062 *  Returns 0, if each file in @files is found in m_source_files,
4063 *  otherwise returns 1
4064 */
4065//--------------------------------------------------
4066int DependencyGenerator::validate (const CmtSystem::cmt_string_vector& files) const
4067{
4068  int n_invalid = 0;
4069  for (int i = 0; i < files.size (); i++)
4070    {
4071      bool valid = false;
4072      for (int j = 0; j < m_source_files.size (); j++)
4073        if (files[i] == m_source_files[j].name ())
4074          {
4075            valid = true;
4076            break;
4077          }
4078      if (!valid)
4079        {
4080          n_invalid += 1;
4081          break;
4082        }
4083    }
4084
4085  return n_invalid;
4086}
Note: See TracBrowser for help on using the repository browser.