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

Last change on this file since 613 was 613, checked in by rybkin, 12 years ago

See C.L. 488

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