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

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

See C.L. 522

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