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

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

See C.L. 524

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