source: CMT/v1r25p20160527/source/cmt_generator.cxx

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

svn merge -r 666:668 HEAD

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