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

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

See C.L. 522

  • Property svn:eol-style set to native
File size: 43.7 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by Grigory Rybkin
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#include <errno.h>
9#include <stdio.h>
10
11#ifndef WIN32
12#include <unistd.h>
13#endif
14
15#include "cmt_generator.h"
16#include "cmt_use.h"
17#include "cmt_symbol.h"
18
19#include "cmt_generators.h"
20#include "cmt_log.h"
21#include "cmt_error.h"
22
23#include "cmt_install_area.h"
24
25//------------------------------------------------------------------------
26void SourceFile::set (const cmt_string name, Language& language, const cmt_string output)
27{
28  m_name = name;
29  m_language = &language;
30  m_output = output;
31 
32  CmtSystem::reduce_file_separators (m_name);
33}
34
35cmt_string SourceFile::name () const
36{
37  return (m_name);
38}
39
40Language& SourceFile::language () const
41{
42  return (*m_language);
43}
44
45cmt_string SourceFile::output () const
46{
47  return (m_output);
48}
49//------------------------------------------------------------------------
50
51//--------------------------------------------------
52CmtGenerator::CmtGenerator ()
53{
54  m_CONSTITUENT.set ("CONSTITUENT");
55  m_LINKMACRO.set ("LINKMACRO");
56  m_DEPENDENCIESOPTS.set ("DEPENDENCIESOPTS");
57  m_DOCPATH.set ("DOCPATH");
58  m_PACKAGEPATH.set ("PACKAGEPATH");
59  m_PACKAGEPREFIX.set ("PACKAGEPREFIX");
60  m_PACKAGE.set ("PACKAGE");
61  m_VERSION.set ("VERSION");
62  m_MGRSTYLE.set ("MGRSTYLE");
63  m_TITLE.set ("TITLE");
64  m_GROUP.set ("GROUP");
65  m_CONSTITUENTSUFFIX.set ("CONSTITUENTSUFFIX");
66  m_LIBRARYSUFFIX.set ("LIBRARYSUFFIX");
67  m_USER.set ("USER");
68  m_DATE.set ("DATE");
69  m_PROTOTARGET.set ("PROTOTARGET");
70  m_OBJS.set ("OBJS");
71  m_CLASSES.set ("CLASSES");
72  m_PROTOSTAMPS.set ("PROTOSTAMPS");
73  m_NAME.set ("NAME");
74  m_FILEPATH.set ("FILEPATH");
75  m_FILESUFFIX.set ("FILESUFFIX");
76  m_SUFFIX.set ("SUFFIX");
77  m_FILENAME.set ("FILENAME");
78  m_LINE.set ("LINE");
79  m_ADDINCLUDE.set ("ADDINCLUDE");
80  m_FULLNAME.set ("FULLNAME");
81  m_DIRNAME.set ("DIRNAME");
82  m_OUTPUTNAME.set ("OUTPUTNAME");
83  m_ALLOS9SOURCES.set ("ALLOS9SOURCES");
84  m_NODEBUGUSELINKOPTS.set ("NODEBUGUSELINKOPTS");
85  m_DEBUGUSELINKOPTS.set ("DEBUGUSELINKOPTS");
86  m_USEINCLUDES.set ("USEINCLUDES");
87  m_HASTARGETTAG.set ("HASTARGETTAG");
88  m_HASDEPENDENCIES.set ("HASDEPENDENCIES");
89  m_HASPROTOTYPES.set ("HASPROTOTYPES");
90  m_ISCHECKGROUP.set ("ISCHECKGROUP");
91}
92
93//--------------------------------------------------
94void CmtGenerator::reset ()
95{
96  m_CONSTITUENT = "";
97  m_LINKMACRO = "";
98  m_DEPENDENCIESOPTS = "";
99  m_DOCPATH = "";
100  m_PACKAGEPATH = "";
101  m_PACKAGEPREFIX = "";
102  m_PACKAGE = "";
103  m_VERSION = "";
104  m_MGRSTYLE = "";
105  m_TITLE = "";
106  m_GROUP = "";
107  m_CONSTITUENTSUFFIX = "";
108  m_LIBRARYSUFFIX = "";
109  m_USER = "";
110  m_DATE = "";
111  m_PROTOTARGET = "";
112  m_OBJS = "";
113  m_CLASSES = "";
114  m_PROTOSTAMPS = "";
115  m_NAME = "";
116  m_FILEPATH = "";
117  m_FILESUFFIX = "";
118  m_SUFFIX = "";
119  m_FILENAME = "";
120  m_LINE = "";
121  m_ADDINCLUDE = "";
122  m_FULLNAME = "";
123  m_OUTPUTNAME = "";
124  m_ALLOS9SOURCES = "";
125  m_NODEBUGUSELINKOPTS = "";
126  m_DEBUGUSELINKOPTS = "";
127  m_USEINCLUDES = "";
128  m_HASTARGETTAG = "";
129  m_HASDEPENDENCIES = "";
130  m_HASPROTOTYPES = "";
131  m_ISCHECKGROUP = "";
132  m_PACKINCLUDES = "";
133  m_PACKOS9      = false;
134  m_GENERATOR    = "";
135
136  is_library     = false;
137  is_application = false;
138  srcdir       = "";
139  docdir       = "";
140  cmtdir       = "";
141  incdir       = "";
142  src          = "$(src)";
143  doc          = "$(doc)";
144  inc          = "$(inc)";
145  mgr          = "$(mgr)";
146  cmt          = "$(cmt)";
147  protos       = "";
148  protonames   = "";
149  os9sources   = "";
150
151  m_source_files.clear ();
152  m_bin = "";
153  m_output_file_name = "";
154  m_output_file = 0;
155  m_constituent = 0;
156
157  Language::setup_all_fragments ();
158
159  CmtSystem::cd (Cmt::get_current_dir ());
160
161  cmt_string branch = CmtSystem::current_branch ();
162
163  if ((branch == "mgr") || (branch == "cmt"))
164    {
165      if (CmtSystem::test_directory ("../src"))
166        {
167          srcdir = "..";
168          srcdir += CmtSystem::file_separator ();
169          srcdir += "src";
170          srcdir += CmtSystem::file_separator ();
171        }
172      else
173        {
174          srcdir = "";
175        }
176
177      if (CmtSystem::test_directory ("../doc"))
178        {
179          docdir = "..";
180          docdir += CmtSystem::file_separator ();
181          docdir += "doc";
182          docdir += CmtSystem::file_separator ();
183        }
184      else
185        {
186          docdir = "";
187        }
188
189      if (CmtSystem::test_directory ("../cmt"))
190        {
191          cmtdir = "..";
192          cmtdir += CmtSystem::file_separator ();
193          cmtdir += "cmt";
194          cmtdir += CmtSystem::file_separator ();
195        }
196      else if (CmtSystem::test_directory ("../mgr"))
197        {
198          cmtdir = "..";
199          cmtdir += CmtSystem::file_separator ();
200          cmtdir += "mgr";
201          cmtdir += CmtSystem::file_separator ();
202        }
203      else
204        {
205          cmtdir = CmtSystem::pwd ();
206          cmtdir += CmtSystem::file_separator ();
207        }
208
209      if (CmtSystem::test_directory ("../src"))
210        {
211          incdir = "..";
212          incdir += CmtSystem::file_separator ();
213          incdir += "src";
214          incdir += CmtSystem::file_separator ();
215        }
216      else
217        {
218          incdir = "";
219        }
220    }
221  else
222    {
223      srcdir = ".";
224      srcdir += CmtSystem::file_separator ();
225      docdir = ".";
226      docdir += CmtSystem::file_separator ();
227      cmtdir = CmtSystem::pwd ();
228      cmtdir += CmtSystem::file_separator ();
229      incdir = ".";
230      incdir += CmtSystem::file_separator ();
231    }
232}
233
234//--------------------------------------------------
235bool CmtGenerator::prepare_output (const cmt_string& package,
236                                   const Constituent& constituent,
237                                   const cmt_string& file)
238{
239  m_PACKAGE = package;
240  m_CONSTITUENT = constituent.name;
241  m_CONSTITUENTSUFFIX = constituent.suffix;
242
243  m_PACKOS9 = constituent.need_OS9;
244
245  m_output_file_name = cmtdir + m_CONSTITUENT + ".";
246
247  if (Cmt::build_nmake ())
248    {
249      m_output_file_name += "nmake";
250    }
251  else
252    {
253      m_output_file_name += "make";
254    }
255 
256  if (file != "") m_output_file_name = file;
257
258  m_output_file_name += "new";
259
260
261  m_output_file = fopen (m_output_file_name.c_str (), "wb");
262  if (m_output_file != NULL)
263    {
264      return (true);
265    }
266  else
267    {
268      return (false);
269    }
270}
271
272//--------------------------------------------------
273void CmtGenerator::check (const cmt_string& name)
274{
275  static cmt_string old;
276  static cmt_string backup;
277
278  old = name;
279
280  int pos = old.find_last_of ("new");
281  old.erase (pos);
282
283  if (!CmtSystem::compare_files (old, name))
284    {
285      backup = old;
286      backup += "sav";
287
288      unlink (backup.c_str ());
289      rename (old.c_str (), backup.c_str ());
290      rename (name.c_str (), old.c_str ());
291    }
292  else
293    {
294      unlink (name);
295    }
296}
297
298//--------------------------------------------------
299void CmtGenerator::commit (const cmt_string& name)
300{
301  static cmt_string old;
302  static cmt_string backup;
303
304  old = name;
305
306  int pos = old.find_last_of ("new");
307  old.erase (pos);
308
309  if (CmtSystem::test_file (old))
310    {
311      backup = old;
312      backup += "sav";
313
314      unlink (backup.c_str ());
315      rename (old.c_str (), backup.c_str ());
316    }
317
318  rename (name.c_str (), old.c_str ());
319}
320
321//--------------------------------------------------
322void CmtGenerator::terminate ()
323{
324  CmtSystem::close_ostream (m_output_file, m_output_file_name);
325  //  fclose (m_output_file);
326
327  //--- Complete the operation --------------
328
329  commit (m_output_file_name);
330}
331
332//--------------------------------------------------
333void CmtGenerator::fill_names_outputs ()
334{
335  bool first = true;
336
337  m_LINE = "";
338  m_OBJS = "";
339
340  for (int i = 0; i < m_source_files.size (); i++)
341    {
342      const SourceFile& file = m_source_files[i];
343      const cmt_string name = file.name ();
344      const cmt_string output = file.output ();
345
346      if (output != "")
347        {
348          if (first)
349            {
350              first = false;
351            }
352          else
353            {
354              m_LINE += " ";
355              m_OBJS += " ";
356            }
357          m_LINE += name;
358          m_OBJS += output;
359        }
360
361      if (Cmt::get_debug ())
362        {
363          cout << "CmtGenerator::fill_names_outputs>" << endl;
364          cout << "name=" << name << " LINE=" << m_LINE << endl;
365          cout << "output=" << output << " OBJS=" << m_OBJS << endl;
366        }
367    }
368
369  filter_path (m_LINE.value);
370}
371
372//--------------------------------------------------
373void CmtGenerator::fill_outputs ()
374{
375  bool first = true;
376
377  m_OBJS = "";
378
379  for (int i = 0; i < m_source_files.size (); i++)
380    {
381      const SourceFile& file = m_source_files[i];
382      const cmt_string output = file.output ();
383
384      if (output != "")
385        {
386          if (first)
387            {
388              first = false;
389            }
390          else
391            {
392              m_OBJS += " ";
393            }
394
395          m_OBJS += output;
396        }
397
398      if (Cmt::get_debug ())
399        {
400          cout << "CmtGenerator::fill_outputs> output=" << output << " OBJS=" << m_OBJS << endl;
401        }
402
403    }
404
405  if (Cmt::get_debug ())
406    {
407      cout << "CmtGenerator::fill_outputs> OBJS=" << m_OBJS << endl;
408    }
409
410}
411
412/*
413//--------------------------------------------------
414void CmtGenerator::prepare_use_context ()
415{
416  cmt_string path;
417  cmt_string substitution;
418
419  Use* use = &Use::current ();
420
421  m_deps_builder.clear ();
422
423  if (use->include_path != "none")
424    {
425      if (use->include_path == "")
426        {
427          m_deps_builder.add (incdir, "$(src)");
428        }
429      else
430        {
431          substitution = use->include_path;
432         
433          path = substitution;
434          Symbol::expand (path);
435         
436          CmtSystem::reduce_file_separators (path);
437
438          m_deps_builder.add (path, substitution);
439        }
440    }
441
442  m_deps_builder.add_includes (*use);
443
444  Use::UsePtrVector& uses = Use::get_ordered_uses ();
445
446  if (uses.size () > 0)
447    {
448      int number;
449
450      for (number = 0; number < uses.size (); number++)
451        {
452          use = uses[number];
453          if (use->discarded) continue;
454
455          if (use->real_path != "")
456            {
457              if (use->include_path != "none")
458                {
459                  if (use->include_path == "")
460                    {
461                      use->get_full_path (path);
462                      path += CmtSystem::file_separator ();
463                      path += "src";
464
465                      substitution = "$(";
466                      substitution += use->prefix;
467                      substitution += "ROOT)";
468                      substitution += CmtSystem::file_separator ();
469                      substitution += "src";
470                      substitution += CmtSystem::file_separator ();
471                    }
472                  else
473                    {
474                      substitution = use->include_path;
475
476                      path = substitution;
477                      Symbol::expand (path);
478
479                      CmtSystem::reduce_file_separators (path);
480                    }
481
482                  m_deps_builder.add (path, substitution);
483                }
484
485              m_deps_builder.add_includes (*use);
486            }
487        }
488    }
489}
490*/
491//--------------------------------------------------
492void CmtGenerator::filter_path (cmt_string& text)
493{
494  CmtSystem::compress_path (text);
495
496  text.replace_all ("./../src/../", "../");
497  text.replace_all ("./../src/", "$(src)");
498
499  text.replace_all (".\\..\\src\\..\\", "..\\");
500  text.replace_all (".\\..\\src\\", "$(src)");
501
502  text.replace_all ("../src/../", "../");
503  text.replace_all ("../src/", "$(src)");
504
505  text.replace_all ("..\\src\\..\\", "..\\");
506  text.replace_all ("..\\src\\", "$(src)");
507
508  text.replace_all ("../doc/../", "../");
509  text.replace_all ("../doc/", "$(doc)");
510
511  text.replace_all ("..\\doc\\..\\", "..\\");
512  text.replace_all ("..\\doc\\", "$(doc)");
513
514  text.replace_all ("$(src)$(src)", "$(src)");
515}
516
517/**
518   Scan a complete file spec (with possibly wild cards and directory)
519   given in full_name ad fill in a vector of found file names.
520
521   Result of the scan is filtered against matching suffixes
522
523   Returns the count of non empty file names really found.
524
525*/
526int CmtGenerator::get_all_files (const cmt_string& full_name,
527                                 const cmt_vector<cmt_regexp>& exclude_exprs,
528                                 const cmt_vector<cmt_regexp>& select_exprs,
529                                 CmtSystem::cmt_string_vector& files)
530{
531  static cmt_string suffix;
532  static cmt_string name;
533
534  bool has_excludes = false;
535  bool has_selects = false;
536
537  suffix = "";
538  name = "";
539
540  files.clear ();
541
542  has_excludes = (exclude_exprs.size () > 0);
543  has_selects = (select_exprs.size () > 0);
544
545  CmtSystem::get_dot_suffix (full_name, suffix);
546
547  bool wilcarded_suffix = false;
548
549  if (suffix == ".*") wilcarded_suffix = true;
550
551  int count = 0;
552
553  if (full_name.find ('*') != cmt_string::npos)
554    {
555      CmtSystem::scan_dir (full_name, files);
556
557      if (Cmt::get_debug ())
558        {
559          cout << "CMT::get_all_files> full_name=" << full_name <<
560            " pwd=" << CmtSystem::pwd () << endl;
561          cout << "CMT::get_all_files> files.size=" <<  files.size () << endl;
562        }
563
564      /**
565
566      We have to treat patterns of the form *.xxx (ie with a
567      suffix) thus we filter out everything that could have been
568      collected with a different suffix because the
569      CmtSystem::scan_dir function only handles patterns of the
570      form xxx* (ie with trailing *)
571
572      [If the original suffix was empty (ie files specified using
573      xx*) this means getting files without any dot-suffix. This
574      may be incorrect??]
575
576      */
577
578      for (int j = 0; j < files.size (); j++)
579        {
580          cmt_string& n = files[j];
581
582          bool rejected = false;
583
584          if (n == "")
585            {
586              rejected = true;
587            }
588
589          if (!rejected && has_selects)
590            {
591              rejected = true;
592
593              for (int k = 0; k < select_exprs.size (); k++)
594                {
595                  const cmt_regexp& exp = select_exprs[k];
596                  if (exp.match (n))
597                    {
598                      rejected = false;
599                      break;
600                    }
601                }
602            }
603
604          if (!rejected && has_excludes)
605            {
606              for (int k = 0; k < exclude_exprs.size (); k++)
607                {
608                  const cmt_regexp& exp = exclude_exprs[k];
609                  if (exp.match (n))
610                    {
611                      rejected = true;
612                      break;
613                    }
614                }
615            }
616
617          if (!rejected)
618            {
619              static cmt_string s;
620
621              CmtSystem::get_dot_suffix (n, s);
622              if (!wilcarded_suffix && (s != suffix)) 
623                {
624                  rejected = true;
625                }
626              else
627                {
628                  count++;
629                }
630            }
631
632          if (Cmt::get_debug ())
633            {
634              if (rejected)
635                {
636                  cout << "CMT::get_all_files> reject " <<  n << endl;
637                }
638              else
639                {
640                  cout << "CMT::get_all_files> keep " <<  n << endl;
641                }
642            }
643
644          if (rejected)
645            {
646              n = "";
647            }
648        }
649    }
650  else
651    {
652      if (full_name != "")
653        {
654          bool rejected = false;
655
656          if (has_excludes)
657            {
658              for (int k = 0; k < exclude_exprs.size (); k++)
659                {
660                  const cmt_regexp& exp = exclude_exprs[k];
661                  if (exp.match (full_name))
662                    {
663                      rejected = true;
664                      break;
665                    }
666                }
667            }
668
669          if (!rejected)
670            {
671              cmt_string& n = files.add ();
672
673              n = full_name;
674
675              count++;
676            }
677        }
678    }
679
680  return (count);
681}
682
683//--------------------------------------------------
684void CmtGenerator::set_full_name (cmt_string& full_name, cmt_string& file)
685{
686  full_name = "";
687
688  Symbol::expand (file);
689
690  if (file == "") return;
691 
692  if (!CmtSystem::absolute_path (file))
693    {
694      full_name = srcdir;
695      if (full_name != "") full_name += CmtSystem::file_separator ();
696    }
697 
698  full_name += file;
699
700  CmtSystem::reduce_file_separators (full_name);
701}
702
703//------------------------------------------------------------------------
704//static ApplicationGenerator ApplicationContext;
705static LibraryGenerator LibraryContext;
706static DocumentGenerator DocumentContext;
707static ReadmeGenerator ReadmeContext;
708static PrototypeGenerator PrototypeContext;
709static DefaultMakefileGenerator DefaultMakefileContext;
710static MSDEVGenerator MSDEVContext;
711static VSNETGenerator VSNETContext;
712static MakeSetupGenerator MakeSetupContext;
713static ConstituentsMakefileGenerator ConstituentsMakefileContext;
714static PackagesMakefileGenerator PackagesMakefileContext;
715static DependencyGenerator DependencyContext;
716
717//--------------------------------------------------
718int Generator::build_msdev_workspace (const Constituent::ConstituentVector& constituents)
719{
720  return (MSDEVContext.build_workspace (constituents));
721}
722
723//--------------------------------------------------
724int Generator::build_msdev (const Constituent& constituent)
725{
726  return (MSDEVContext.build_project (constituent));
727}
728
729//--------------------------------------------------
730int Generator::build_vsnet_workspace (const Constituent::ConstituentVector& constituents)
731{
732  return (VSNETContext.build_workspace (constituents));
733}
734
735//--------------------------------------------------   
736int Generator::build_vsnet (const Constituent& constituent)
737{
738  return (VSNETContext.build_project (constituent));
739}
740
741//--------------------------------------------------
742void Generator::build_make_setup (const cmt_string& package)
743{
744  MakeSetupContext.build (package);
745}
746
747//--------------------------------------------------
748void Generator::build_constituents_makefile (const cmt_string& package,
749                                             const cmt_string& file)
750//                                           const CmtSystem::cmt_string_vector& arguments)
751{
752  ConstituentsMakefileContext.build (package, file);
753  //  ConstituentsMakefileContext.build (package, arguments);
754}
755
756//--------------------------------------------------
757int Generator::build_constituent_infile (const Constituent& constituent,
758                                         const cmt_string& outdir,
759                                         bool usecmt)
760{
761  cmt_string file (constituent.name + ".in");
762  if (outdir != "")
763    {
764      if (outdir [outdir.size () - 1] != CmtSystem::file_separator ())
765        file = outdir + CmtSystem::file_separator () + file;
766      else
767        file = outdir + file;
768    }
769
770  int retval (0);
771  static InGenerator InGen (usecmt, false);
772
773  bool gen (true);
774  ostringstream os;
775  ofstream s;
776  //  s.open (file);
777  s.open (file, ios::in);
778  if (s) // file already exists
779    {
780      retval = InGen.build (constituent, os);
781      ostringstream osn;
782      osn << s.rdbuf ();
783      if (os.str () == osn.str ())
784        {
785          //      cerr << file << " up-to-date" << endl;
786          gen = false;
787        }
788    }
789  s.clear ();
790  s.close ();
791  s.clear ();
792  if (0 != retval) return retval;
793  if (gen)
794    {
795      s.open (file);
796      if (!s)
797        {
798          CmtError::set (CmtError::file_access_error, file);
799          return -1;
800        }
801      s.exceptions (ios::failbit | ios::badbit);
802      try
803        {
804          if (os.str ().size () != 0)
805            {
806              //  cerr << file << " contents already generated" << endl;
807              s << os.str ();
808            }
809          else
810            {
811              retval = InGen.build (constituent, s);
812            }
813          s.close (); // ios_base::failbit
814        }
815      catch (const ios::failure& e)
816        {
817          CmtSystem::close_ostream (NULL, file + ": " + cmt_string (e.what ()));
818          return -1;
819        }
820    }
821
822      //  InGen.build (constituent, s);
823
824  //  s.close (); // ios_base::failbit
825
826  return retval;
827}
828
829//--------------------------------------------------
830int Generator::build_library_links_infile (const cmt_string& outdir)
831{
832#ifndef WIN32
833  cmt_string file ("library_links.in");
834  if (outdir != "")
835    {
836      if (outdir [outdir.size () - 1] != CmtSystem::file_separator ())
837        file = outdir + CmtSystem::file_separator () + file;
838      else
839        file = outdir + file;
840    }
841
842  bool wrote (false);
843  ostringstream ls;
844
845  Use::UsePtrVector& Uses = Use::get_ordered_uses ();
846  Use& current_use = Use::current ();
847  Use::UsePtrVector uses (Uses);
848  uses.push_back (&Use::current ());
849
850  cmt_string shlibsuffix;
851  {
852    Symbol* macro = Symbol::find ("shlibsuffix");
853    if (macro == 0)
854      {
855        CmtError::set(CmtError::configuration_error, "shlibsuffix undefined");
856        return -1;
857      }
858    shlibsuffix = macro->build_macro_value ();
859    Symbol::expand (shlibsuffix);
860  }
861
862  for (int i = 0; i < uses.size (); i++)
863    {
864      Use* use = uses[i];
865
866      if (use == 0) continue;
867      if (use->discarded) continue;
868      if (use->m_hidden) continue;
869
870      if (use->get_package_name () == "CMT") continue;
871      if (!use->located ()) continue;
872      //use->remove_library_links (cmtinstallarea, tag, shlibsuffix, symunlinkcmd);
873      cmt_string s (use->get_package_name ());
874      s += "_libraries";
875      const Symbol* libraries_macro = Symbol::find (s);
876      if (libraries_macro == 0) continue;
877      cmt_string libraries = libraries_macro->build_macro_value ();
878      Symbol::expand (libraries);
879      static CmtSystem::cmt_string_vector values;
880     
881      CmtSystem::split (libraries, " \t", values);
882     
883      for (int j = 0; j < values.size (); j++)
884        {
885          const cmt_string& library = values[j];
886         
887          static cmt_string libname;
888          static cmt_string name;
889         
890          // Is it a simple name or a complete path?
891         
892          libname = library;
893          Symbol::expand (libname);
894          if (0 == libname.size ()) continue;
895         
896          CmtSystem::cmt_string_vector paths;
897          use->absolute_library_path (libname,
898                                      shlibsuffix, 
899                                      paths);
900          for (int k = 0; k < paths.size (); k++)
901            {
902              cmt_string path (paths[k]);
903              Symbol::expand (path);
904              if (0 == path.size ()) continue;
905              if (wrote) ls << " ";
906              else wrote = true;
907              ls << CmtSystem::quote (path, " \t");
908            }
909        }
910    }
911  ostringstream os;
912  if (wrote)
913    {
914      os << "macro ";
915      os << current_use.get_package_name () + "_libraries ";
916      os << CmtSystem::quote (ls.str ().c_str (), " \t");
917      os << "\n";
918
919      os << "macro shlibsuffix ";
920      os << CmtSystem::quote (shlibsuffix, " \t");
921      os << "\n";
922
923      cmt_string symlinkcmd;
924      {
925        Symbol* macro = Symbol::find ("library_install_command");
926        if (macro != 0)
927          {
928            symlinkcmd = macro->build_macro_value ();
929            Symbol::expand (symlinkcmd);
930          }
931      }
932      os << "macro library_install_command ";
933      os << CmtSystem::quote (symlinkcmd, " \t");
934      os << "\n";
935
936      cmt_string symunlinkcmd;
937      {
938        Symbol* macro = Symbol::find ("symunlink");
939        if (macro != 0)
940          {
941            symunlinkcmd = macro->build_macro_value ();
942            Symbol::expand (symunlinkcmd);
943          }
944      }
945      os << "macro symunlink ";
946      os << CmtSystem::quote (symunlinkcmd, " \t");
947      os << "\n";
948
949      if (current_use.get_strategy ("InstallArea"))
950        {
951          os << "build_strategy with_installarea\n";
952
953          const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
954         
955          cmt_string cmtinstallarea = ia_mgr.get_installarea ();
956          {
957            Symbol* symbol = Symbol::find ("CMTINSTALLAREA");
958            if (symbol != 0)
959              {
960                cmtinstallarea = symbol->build_macro_value ();
961                Symbol::expand (cmtinstallarea);
962              }
963          }
964          os << "macro CMTINSTALLAREA ";
965          os << CmtSystem::quote (cmtinstallarea, " \t");
966          os << "\n";
967
968          cmt_string tag;
969          {
970            Symbol* macro = Symbol::find ("tag");
971            if (macro != 0)
972              {
973                tag = macro->build_macro_value ();
974                Symbol::expand (tag);
975              }
976          }
977          os << "macro tag ";
978          os << CmtSystem::quote (tag, " \t");
979          os << "\n";
980        }
981      //      cerr << os.str ();
982    }
983
984  // Write input requirements file
985
986  //  static InGenerator InGen (usecmt);
987
988  bool gen (true);
989  //  ostringstream os;
990  ofstream s;
991  //  s.open (file);
992  s.open (file, ios::in);
993  if (s) // file already exists
994    {
995      //      InGen.build (constituent, os);
996      ostringstream osn;
997      osn << s.rdbuf ();
998      if (os.str () == osn.str ())
999        {
1000          //      cerr << file << " up-to-date" << endl;
1001          gen = false;
1002        }
1003    }
1004  s.clear ();
1005  s.close ();
1006  s.clear ();
1007  if (gen)
1008    {
1009      s.open (file);
1010      if (!s)
1011        {
1012          CmtError::set (CmtError::file_access_error, file);
1013          return -1;
1014        }
1015      s.exceptions (ios::failbit | ios::badbit);
1016      try
1017        {
1018          //      if (os.str ().size () != 0)
1019          //        {
1020              //  cerr << file << " contents already generated" << endl;
1021              s << os.str ();
1022              //            }
1023              //          else
1024              //            {
1025              //              InGen.build (constituent, s);
1026              //            }
1027          s.close (); // ios_base::failbit
1028        }
1029      catch (const ios::failure& e)
1030        {
1031          CmtSystem::close_ostream (NULL, file + ": " + cmt_string (e.what ()));
1032          return -1;
1033        }
1034    }
1035
1036#endif
1037  return 0;
1038}
1039
1040//--------------------------------------------------
1041int Generator::build_dependencies_infile (const Constituent* pconstituent,
1042                                          const cmt_string& outdir,
1043                                          bool usecmt)
1044{
1045  cmt_string file ("dependencies");
1046  if (0 != pconstituent)
1047    file += "_" + pconstituent->name;
1048  file += ".in";
1049
1050  if (outdir != "")
1051    {
1052      if (outdir [outdir.size () - 1] != CmtSystem::file_separator ())
1053        file = outdir + CmtSystem::file_separator () + file;
1054      else
1055        file = outdir + file;
1056    }
1057
1058  ostringstream os;
1059 
1060  cmt_string preprocessor;
1061  Symbol* macro = Symbol::find ("preprocessor_command");
1062  if (macro != 0)
1063    {
1064      preprocessor = macro->resolve_macro_value ();
1065    }
1066
1067  if (preprocessor == "")
1068    {
1069      const Use* current_use = &Use::current ();
1070      Use::UsePtrVector uses (Use::get_ordered_uses ());
1071      uses.push_back (&Use::current ());
1072     
1073      if (current_use->include_path == "none")
1074        os << "include_path none\n";
1075
1076      for (int i = uses.size () - 1; i >= 0; i--)
1077        {
1078          const Use* use = uses[i];
1079          if (use->discarded) continue;
1080          if (use->m_hidden) continue;
1081          if (!use->located ()) continue;
1082         
1083          cmt_string package_name = use->get_package_name ();
1084          if (package_name == "CMT") continue;
1085         
1086          const Symbol* filter_macro = Symbol::find (package_name + "_header_file_filter");
1087          if (filter_macro == 0) continue;
1088          const cmt_string filter_expr (filter_macro->resolve_macro_value ());
1089          if (filter_expr.size () == 0) continue;
1090         
1091          const Symbol* stamp_macro = Symbol::find (package_name + "_header_file_stamp");
1092          cmt_string stamp;
1093          if (stamp_macro != 0)
1094            {
1095              stamp = stamp_macro->resolve_macro_value ();
1096            }
1097          else
1098            {
1099              use->get_full_path (stamp);
1100              switch (use->style)
1101                {
1102                case cmt_style:
1103                  stamp += CmtSystem::file_separator ();
1104                  stamp += "cmt";
1105                  break;
1106                case mgr_style:
1107                  stamp += CmtSystem::file_separator ();
1108                  stamp += "mgr";
1109                  break;
1110                }
1111              stamp += CmtSystem::file_separator ();
1112              stamp += "cmt_header_file.stamp";
1113            }
1114          if (!CmtSystem::test_file (stamp)) continue;
1115
1116          os << "macro " + package_name + "_header_file_filter ";
1117          os << CmtSystem::quote (filter_expr, " \t");
1118          //os << CmtSystem::quote (filter_macro->resolve_macro_value (), " \t");
1119          os << "\n";
1120          os << "macro " + package_name + "_header_file_stamp ";
1121          os << CmtSystem::quote (stamp, " \t");
1122          os << "\n";
1123        }
1124    }
1125  else
1126    {
1127      os << "macro preprocessor_command ";
1128      os << CmtSystem::quote (preprocessor, " \t");
1129      os << "\n";
1130      macro = Symbol::find ("includes");
1131      if (0 != macro)
1132        {
1133          os << "macro includes ";
1134          os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1135          os << "\n";
1136        }
1137      if (0 == pconstituent)
1138        {
1139          const Constituent::ConstituentVector& constituents =
1140            Constituent::constituents ();
1141          for (int n = 0; n < constituents.size (); n++)
1142            {
1143              const Constituent& constituent = constituents[n];
1144              if (constituent.has_target_tag) continue;
1145              if (constituent.type == Document) continue;
1146              cmt_string prefix;
1147              switch (constituent.type)
1148                {
1149                case Application:
1150                  prefix = "app_";
1151                  break;
1152                case Library:
1153                  prefix = "lib_";
1154                  break;
1155                }
1156              cmt_string macro_name (prefix + constituent.name + "_cppflags");
1157              macro = Symbol::find (macro_name);
1158              if (0 != macro)
1159                {
1160                  os << "macro_append " + macro_name + " ";
1161                  os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1162                  os << "\n";
1163                }
1164            }
1165        }
1166      else if (pconstituent->type != Document)
1167        {
1168          const Constituent& constituent = *pconstituent;
1169          cmt_string prefix;
1170          switch (constituent.type)
1171            {
1172            case Application:
1173              prefix = "app_";
1174              break;
1175            case Library:
1176              prefix = "lib_";
1177              break;
1178            }
1179          cmt_string macro_name (prefix + constituent.name + "_cppflags");
1180          macro = Symbol::find (macro_name);
1181          if (0 != macro)
1182            {
1183              os << "macro_append " + macro_name + " ";
1184              os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1185              os << "\n";
1186            }
1187        }
1188    }
1189
1190  // Write input requirements file
1191
1192  bool gen (true);
1193  //  ostringstream os;
1194  ofstream s;
1195  //  s.open (file);
1196  s.open (file, ios::in);
1197  if (s) // file already exists
1198    {
1199      //      InGen.build (constituent, os);
1200      ostringstream osn;
1201      osn << s.rdbuf ();
1202      if (os.str () == osn.str ())
1203        {
1204          //      cerr << file << " up-to-date" << endl;
1205          gen = false;
1206        }
1207    }
1208  s.clear ();
1209  s.close ();
1210  s.clear ();
1211  if (gen)
1212    {
1213      s.open (file);
1214      if (!s)
1215        {
1216          CmtError::set (CmtError::file_access_error, file);
1217          return -1;
1218        }
1219      s.exceptions (ios::failbit | ios::badbit);
1220      try
1221        {
1222          //      if (os.str ().size () != 0)
1223          //        {
1224              //  cerr << file << " contents already generated" << endl;
1225              s << os.str ();
1226              //            }
1227              //          else
1228              //            {
1229              //              InGen.build (constituent, s);
1230              //            }
1231          s.close (); // ios_base::failbit
1232        }
1233      catch (const ios::failure& e)
1234        {
1235          CmtSystem::close_ostream (NULL, file + ": " + cmt_string (e.what ()));
1236          return -1;
1237        }
1238    }
1239
1240  return 0;
1241}
1242
1243//--------------------------------------------------
1244int Generator::build_constituent_makefile (const Constituent& constituent,
1245                                           bool& dependencies,
1246                                           const cmt_string& file)
1247{
1248  const cmt_string& package = Cmt::get_current_package ();
1249
1250  switch (constituent.type)
1251    {
1252    case Application:
1253      //ApplicationContext.build (package, constituent, file);
1254      //break;
1255    case Library:
1256      LibraryContext.build (package, constituent, dependencies, file);
1257      break;
1258    case Document:
1259      DocumentContext.build (package, constituent, dependencies, file);
1260      break;
1261    }
1262
1263  return (0);
1264}
1265
1266//--------------------------------------------------
1267void Generator::build_constituent_makefile (const CmtSystem::cmt_string_vector& arguments)
1268{
1269  cmt_string name;
1270  cmt_string file;
1271
1272  if (arguments.size () == 1)
1273    {
1274      file = "";
1275      name = arguments[0];
1276    }
1277  else if (arguments.size () == 2) // arguments[0].substr (0, 5) == "-out="
1278    {
1279      cmt_string arg = arguments[0];
1280      arg.erase (0, 5);
1281      file = arg;
1282      name = arguments[1];
1283    }
1284  else
1285    {
1286      CmtMessage::error ("build constituent_makefile : wrong arguments");
1287      //      cerr << "#CMT> build constituent_makefile : wrong arguments" << endl;
1288      return;
1289    }
1290
1291  const Constituent* constituent = Constituent::find (name);
1292  if (constituent != 0)
1293    {
1294      bool dependencies (false);
1295      build_constituent_makefile (*constituent, dependencies, file);
1296    }
1297}
1298
1299//--------------------------------------------------
1300void Generator::build_default_makefile ()
1301{
1302  DefaultMakefileContext.build ();
1303}
1304
1305//--------------------------------------------------
1306void Generator::build_packages_makefile (const cmt_string& package,
1307                                         const cmt_string& file)
1308{
1309  PackagesMakefileContext.build (package, file);
1310  //  UsesMakefileContext.build (package, file);
1311}
1312
1313//--------------------------------------------------
1314void Generator::build_dependencies (const CmtSystem::cmt_string_vector& arguments)
1315{
1316  DependencyContext.build (arguments);
1317}
1318
1319//--------------------------------------------------
1320void Generator::build_prototype (const cmt_string& file_name)
1321{
1322  PrototypeContext.build (file_name);
1323}
1324
1325//--------------------------------------------------
1326void Generator::build_readme (const CmtSystem::cmt_string_vector& arguments)
1327{
1328  ReadmeContext.build (arguments);
1329}
1330
1331class WinDefAwk : public PAwk
1332{
1333public :
1334  WinDefAwk (const cmt_string& library_name)
1335  {
1336    m_name = library_name;
1337  }
1338
1339  void begin ()
1340  {
1341    cout << "LIBRARY " << m_name << endl;
1342    cout << "EXPORTS" << endl;
1343  }
1344
1345  void filter (const cmt_string& line)
1346  {
1347    if (line.find ("External") == cmt_string::npos) return;
1348    if (line.find ("??_") != cmt_string::npos)
1349      {
1350        if (line.find ("operator/=") == cmt_string::npos) return;
1351        // Keep operator /= .
1352      }
1353
1354    CmtSystem::cmt_string_vector words;
1355    CmtSystem::split (line, " \t", words);
1356    if (words.size () >= 7)
1357      {
1358        int pos = 7;
1359
1360        cmt_string& fifth_word = words[4];
1361        if (fifth_word == "()") pos = 7;
1362        else if (fifth_word == "External") pos = 6;
1363        else return;
1364
1365        cmt_string& symbol = words[pos];
1366        if (symbol[0] == '_') symbol.erase (0, 1);
1367        symbol.replace_all ("\r", "");
1368        symbol.replace_all ("\n", "");
1369
1370        if ((pos == 6) && 
1371            ((line.find(": static") != cmt_string::npos) ||
1372             (line.find("(class") != cmt_string::npos)) )
1373          {
1374            // static data members are not DATA :
1375            // extern objects are not DATA :
1376            cout << " " << symbol << " " << endl;
1377          } 
1378        else if (pos == 6)
1379          {
1380            // DATA :
1381            cout << " " << symbol << "\tDATA" << endl;
1382          } 
1383        else
1384          {
1385            // code :
1386            cout << " " << symbol << " " << endl;
1387          } 
1388      }
1389  }
1390
1391  void end ()
1392  {
1393  }
1394
1395private:
1396  cmt_string m_name;
1397};
1398
1399//--------------------------------------------------
1400//void Generator::build_windefs (const cmt_string& library_name)
1401void Generator::build_windefs (const CmtSystem::cmt_string_vector& arguments)
1402{
1403  cmt_string name;
1404  //  CmtSystem::cmt_string_vector files;
1405  cmt_string files;
1406
1407  for (int i = 0; i < arguments.size (); i++)
1408    {
1409      const cmt_string& w = arguments[i];
1410      if (w.substr (0, 6) == "-name=" || w.substr (0, 6) == "-name:" ||
1411          w.substr (0, 6) == "/name:" || w.substr (0, 6) == "/name=")
1412        w.substr (6, name);
1413      else if (w.substr (0, 1) == "@" && w.size () > 1)
1414        {
1415          cmt_string commandfile;
1416          w.substr (1, commandfile);
1417          if (!CmtSystem::test_file (commandfile))
1418            {
1419              CmtMessage::warning ("No such file `" + commandfile + "'.");
1420              continue;
1421            }
1422          cmt_string text;
1423          if (!text.read (commandfile))
1424            {
1425              CmtMessage::warning ("Could not read `" + commandfile + "'.");
1426              continue;
1427            }
1428          text.replace_all ("\r", " ");
1429          text.replace_all ("\n", " ");
1430          files += " " + text;
1431          /*
1432          CmtSystem::cmt_string_vector words;
1433          CmtSystem::split (text, " \t", words);
1434          for (int i = 0; i < words.size (); i++)
1435            {
1436              files.push_back (words[i]);
1437            }
1438          */
1439        }
1440      else
1441        files += " " + w;
1442      //        files.push_back (w);
1443    }
1444
1445  if (files.size () == 0)
1446    {
1447      CmtMessage::error ("build_windefs: no files specified");
1448      return;
1449    }
1450  if (name == "")
1451    {
1452      CmtSystem::cmt_string_vector words;
1453      CmtSystem::split (files, " \t", words);
1454      if (words.size () == 0)
1455        {
1456          CmtMessage::error ("build_windefs: no files specified");
1457          return;
1458        }
1459      cmt_string suffix;
1460      CmtSystem::get_dot_suffix (words[0], suffix);
1461      CmtSystem::basename (words[0], suffix, name);
1462    }
1463  if (name == "")
1464    {
1465      CmtMessage::error ("build_windefs: cannot determine library name");
1466      return;
1467    }
1468
1469  //  cmt_string bin;
1470
1471  //  CmtSystem::dirname (library_name, bin);
1472  //  CmtSystem::get_dot_suffix (library_name, suffix);
1473  //  CmtSystem::basename (library_name, suffix, name);
1474 
1475  //  if (!CmtSystem::cd (bin)) return;
1476 
1477  //  cmt_string command;
1478 
1479  cmt_string command ("dumpbin /symbols");
1480  //  command += library_name;
1481  /*
1482  for (int i = 0; i < files.size (); i++)
1483    {
1484      command += " " + files[i];
1485    }
1486  */
1487  command += " " + files;
1488       
1489  WinDefAwk filter (name);
1490 
1491  filter.run (command, "SECT");
1492}
1493
1494//--------------------------------------------------
1495void Packager::begin ()
1496{
1497  m_package_name = "";
1498}
1499
1500void Packager::filter (const cmt_string& line)
1501{
1502  CmtSystem::cmt_string_vector words;
1503
1504  CmtSystem::split (line, " ", words);
1505  if (words.size () > 1)
1506    {
1507      cmt_string& w = words[0];
1508
1509      if (w == "package")
1510        {
1511          m_package_name = words[1];
1512
1513          int pos = m_package_name.find (";");
1514          if (pos != cmt_string::npos) m_package_name.erase (pos);
1515          m_package_name.replace_all (".", CmtSystem::file_separator ());
1516        }
1517    }
1518}
1519
1520cmt_string& Packager::package_name ()
1521{
1522  return (m_package_name);
1523}
1524
1525//------------------------------------------------------------------------
1526InGenerator::Buffer::Buffer ()
1527  : m_initialized (false), m_usecmt (true)
1528{ }
1529
1530//------------------------------------------------------------------------
1531void InGenerator::Buffer::set_names (const CmtSystem::cmt_string_vector& names)
1532{
1533  m_names = names;
1534}
1535
1536//------------------------------------------------------------------------
1537int InGenerator::Buffer::print (ostream& s)
1538{
1539  int retval (0);
1540  retval = initialize ();
1541  if (0 > retval) return retval;
1542  s << m_buffer.str ();
1543  return 0;
1544}
1545
1546//------------------------------------------------------------------------
1547void InGenerator::Buffer::set_uses (bool usecmt)
1548{
1549  m_usecmt = usecmt;
1550}
1551
1552//------------------------------------------------------------------------
1553void InGenerator::Buffer::set_pedantic (bool pedantic)
1554{
1555  m_pedantic = pedantic;
1556}
1557
1558//------------------------------------------------------------------------
1559int InGenerator::Languages::initialize ()
1560{
1561  int errors (0);
1562  if (m_initialized) return - errors;
1563  m_initialized = true;
1564  for (int i = 0; i < m_names.size (); i++)
1565    {
1566      const cmt_string& name = m_names[i];
1567      Language& p (Language::find (name));
1568      if (Language::null () == p)
1569        {
1570          CmtError::set (CmtError::language_not_found, name);
1571          errors += 1;
1572          continue;
1573        }
1574      p.show (Requirements, m_buffer);
1575      /*
1576      if (!p->use->get_package ()->is_cmt ())
1577        p->print (Requirements, m_buffer);
1578      */
1579    }
1580  //  cerr << "Languages::initialize: " << m_buffer.str ();
1581  return - errors;
1582}
1583
1584//------------------------------------------------------------------------
1585int InGenerator::Fragments::initialize ()
1586{
1587  int errors (0);
1588  if (m_initialized) return - errors;
1589  m_initialized = true;
1590  for (int i = 0; i < m_names.size (); i++)
1591    {
1592      const cmt_string& name = m_names[i];
1593      if (Cmt::get_debug ())
1594        {
1595          cout << "InGenerator::Fragments::initialize> " << name << endl;
1596        }
1597      Fragment* fragment (Fragment::find (name));
1598      if (0 == fragment)
1599        {
1600          if (m_pedantic)
1601            {
1602              CmtError::set (CmtError::fragment_not_found, name + " (standard)");
1603              errors += 1;
1604            }
1605          else
1606            {
1607              CmtMessage::warning
1608                (CmtError::get_error_name (CmtError::fragment_not_found)
1609                 + ": " + name + " (standard)");
1610            }
1611          continue;
1612        }
1613      if (m_usecmt || !fragment->use->get_package ()->is_cmt ())
1614        if (1 != fragment->print (Requirements, m_buffer))
1615          {
1616            if (m_pedantic)
1617              {
1618                CmtError::set (CmtError::fragment_not_found, name + " (standard)");
1619                errors += 1;
1620              }
1621            else
1622              {
1623                CmtMessage::warning
1624                  (CmtError::get_error_name (CmtError::fragment_not_found)
1625                   + ": " + name + " (standard)");
1626              }
1627            continue;
1628          }
1629    }
1630  //  cerr << "initialize: " << m_buffer.str ();
1631  return - errors;
1632}
1633
1634//------------------------------------------------------------------------
1635InGenerator::InGenerator (bool usecmt, bool pedantic)
1636  : m_usecmt (usecmt), m_pedantic (pedantic)
1637{
1638  m_pedantic = (0 != CmtSystem::getenv ("CMTPEDANTIC").size () ||
1639                0 != CmtSystem::getenv ("PEDANTIC").size ());
1640
1641  m_common.set_pedantic (m_pedantic);
1642  m_application.set_pedantic (m_pedantic);
1643  m_application_library.set_pedantic (m_pedantic);
1644  m_library.set_pedantic (m_pedantic);
1645  m_document.set_pedantic (m_pedantic);
1646  m_languages.set_pedantic (m_pedantic);
1647
1648  CmtSystem::cmt_string_vector common;
1649  common.push_back ("make_header");
1650  common.push_back ("dependencies");
1651  common.push_back ("cleanup_header");
1652  m_common.set_names (common);
1653  m_common.set_uses (usecmt);
1654
1655  CmtSystem::cmt_string_vector application;
1656  application.push_back ("java_header");
1657  application.push_back ("application_header");
1658  application.push_back ("application");
1659  application.push_back ("check_java");
1660  application.push_back ("cleanup_application");
1661  application.push_back ("cleanup_objects");
1662  application.push_back ("check_application");
1663
1664  CmtSystem::cmt_string_vector application_library;
1665  application_library.push_back ("protos_header");
1666  application_library.push_back ("buildproto");
1667  application_library.push_back ("dependencies_and_triggers");
1668  application_library.push_back ("java");
1669  application_library.push_back ("java_copy");
1670  application_library.push_back ("cleanup");
1671  application_library.push_back ("cleanup_java");
1672  m_application_library.set_names (application_library);
1673  m_application_library.set_uses (usecmt);
1674
1675  CmtSystem::cmt_string_vector library;
1676  library.push_back ("jar_header");
1677  library.push_back ("library_header");
1678  library.push_back ("jar");
1679  library.push_back ("library_no_share");
1680  library.push_back ("library_no_static");
1681  library.push_back ("library");
1682  library.push_back ("cleanup_library");
1683
1684  CmtSystem::cmt_string_vector languages;
1685  Language::LanguageVector& Languages = Language::languages ();
1686  for (int n = 0; n < Languages.size (); n++)
1687    {
1688      Language& language = Languages[n];
1689      //language.setup_fragments ();
1690      application.push_back (language.fragment_name); //application.name ();
1691      if (!(language == "java"))
1692        library.push_back (language.fragment_name + "_library"); //library.name ();
1693      if (m_usecmt || !language.m_use->get_package ()->is_cmt ())
1694//       if (!language.m_use->get_package ()->is_cmt ())
1695        {
1696          languages.push_back (language.m_name);
1697        }
1698      else if (language.dependencies_options () !=
1699          language.dependencies_options_expanded ())
1700        {
1701          languages.push_back (language.m_name);
1702        }
1703    }
1704  m_languages.set_names (languages);
1705  m_languages.set_uses (usecmt);
1706  m_application.set_names (application);
1707  m_application.set_uses (usecmt);
1708  m_library.set_names (library);
1709  m_library.set_uses (usecmt);
1710 
1711  CmtSystem::cmt_string_vector document;
1712  document.push_back ("document_header");
1713  document.push_back ("dependency");
1714  m_document.set_names (document);
1715  m_document.set_uses (usecmt);
1716}
1717
1718//------------------------------------------------------------------------
1719int InGenerator::build (const Constituent& constituent, ostream& s)
1720{
1721  int retval (0);
1722
1723  constituent.show (s);
1724  retval += m_common.print (s);
1725
1726  switch (constituent.type)
1727    {
1728    case Application:
1729      retval += m_application.print (s);
1730      retval += m_application_library.print (s);
1731      retval += m_languages.print (s);
1732      break;
1733    case Library:
1734      retval += m_application_library.print (s);
1735      retval += m_library.print (s);
1736      retval += m_languages.print (s);
1737      break;
1738    case Document:
1739      Fragment* fragment (Fragment::find (constituent.generator));
1740      if (Cmt::get_debug ())
1741        {
1742          cout << "InGenerator::build> " << constituent.generator
1743               << " |name> " << constituent.name << endl;
1744        }
1745      if (0 == fragment)
1746        {
1747          CmtError::set (CmtError::fragment_not_found, constituent.generator
1748                         + " (document " + constituent.name + ")");
1749          return retval -= 1;
1750        }
1751      if (m_usecmt || !fragment->use->get_package ()->is_cmt ())
1752        if (1 != fragment->print (Requirements, s))
1753          {
1754            CmtError::set (CmtError::fragment_not_found, constituent.generator
1755                           + " (document " + constituent.name + ")");
1756            return retval -= 1;
1757          }
1758      if (0 != fragment->header.size ())
1759        {
1760          if (Cmt::get_debug ())
1761            {
1762              cout << "InGenerator::build> " << fragment->header
1763                   << " |name> " << constituent.name << endl;
1764            }
1765          Fragment* header (Fragment::find (fragment->header));
1766          if (0 == header)
1767            {
1768              CmtError::set (CmtError::fragment_not_found, fragment->header
1769                             + " (document " + constituent.name + ")");
1770              return retval -= 1;
1771            }
1772          //      if (header->use != fragment->use &&
1773          if (m_usecmt || !header->use->get_package ()->is_cmt ())
1774            if (1 != header->print (Requirements, s))
1775              {
1776                CmtError::set (CmtError::fragment_not_found, fragment->header
1777                               + " (document " + constituent.name + ")");
1778                return retval -= 1;
1779              }
1780        }
1781      if (0 != fragment->trailer.size ())
1782        {
1783          if (Cmt::get_debug ())
1784            {
1785              cout << "InGenerator::build> " << fragment->trailer
1786                   << " |name> " << constituent.name << endl;
1787            }
1788          Fragment* trailer (Fragment::find (fragment->trailer));
1789          if (0 == trailer)
1790            {
1791              CmtError::set (CmtError::fragment_not_found, fragment->trailer
1792                             + " (document " + constituent.name + ")");
1793              return retval -= 1;
1794            }
1795          //      if (trailer->use != fragment->use &&
1796          if (m_usecmt || !trailer->use->get_package ()->is_cmt ())
1797            if (1 != trailer->print (Requirements, s))
1798              {
1799                CmtError::set (CmtError::fragment_not_found, fragment->trailer
1800                               + " (document " + constituent.name + ")");
1801                return retval -= 1;
1802              }
1803        }
1804      retval += m_document.print (s);
1805      break;
1806    }
1807
1808  if (m_pedantic)
1809    return retval;
1810  else
1811    return 0;
1812}
1813//------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.