source: CMT/HEAD/source/cmt_generators.cxx @ 595

Last change on this file since 595 was 595, checked in by rybkin, 13 years ago

See C.L. 472

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