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

Last change on this file since 547 was 547, checked in by rybkin, 14 years ago

See C.L. 432

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