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

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

See C.L. 497

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