source: CMT/v1r25p20140131/source/cmt_generators.cxx

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

svn merge -r 666:668 HEAD

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