source: CMT/v1r25p20130606/source/cmt_generators.cxx

Last change on this file was 637, checked in by rybkin, 11 years ago

merge -r 618:627 HEAD

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