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

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

See C.L. 511

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