source: CMT/v1r25-branch/source/cmt_generator.cxx @ 664

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

merge -r 646:663 HEAD

  • Property svn:eol-style set to native
File size: 43.6 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                }
1109              stamp += CmtSystem::file_separator ();
1110              stamp += "cmt_header_file.stamp";
1111            }
1112          if (!CmtSystem::test_file (stamp)) continue;
1113
1114          os << "macro " + package_name + "_header_file_filter ";
1115          os << CmtSystem::quote (filter_expr, " \t");
1116          //os << CmtSystem::quote (filter_macro->resolve_macro_value (), " \t");
1117          os << "\n";
1118          os << "macro " + package_name + "_header_file_stamp ";
1119          os << CmtSystem::quote (stamp, " \t");
1120          os << "\n";
1121        }
1122    }
1123  else
1124    {
1125      os << "macro preprocessor_command ";
1126      os << CmtSystem::quote (preprocessor, " \t");
1127      os << "\n";
1128      macro = Symbol::find ("includes");
1129      if (0 != macro)
1130        {
1131          os << "macro includes ";
1132          os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1133          os << "\n";
1134        }
1135      if (0 == pconstituent)
1136        {
1137          const Constituent::ConstituentVector& constituents =
1138            Constituent::constituents ();
1139          for (int n = 0; n < constituents.size (); n++)
1140            {
1141              const Constituent& constituent = constituents[n];
1142              if (constituent.has_target_tag) continue;
1143              if (constituent.type == Document) continue;
1144              cmt_string prefix;
1145              switch (constituent.type)
1146                {
1147                case Application:
1148                  prefix = "app_";
1149                  break;
1150                case Library:
1151                  prefix = "lib_";
1152                  break;
1153                }
1154              cmt_string macro_name (prefix + constituent.name + "_cppflags");
1155              macro = Symbol::find (macro_name);
1156              if (0 != macro)
1157                {
1158                  os << "macro_append " + macro_name + " ";
1159                  os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1160                  os << "\n";
1161                }
1162            }
1163        }
1164      else if (pconstituent->type != Document)
1165        {
1166          const Constituent& constituent = *pconstituent;
1167          cmt_string prefix;
1168          switch (constituent.type)
1169            {
1170            case Application:
1171              prefix = "app_";
1172              break;
1173            case Library:
1174              prefix = "lib_";
1175              break;
1176            }
1177          cmt_string macro_name (prefix + constituent.name + "_cppflags");
1178          macro = Symbol::find (macro_name);
1179          if (0 != macro)
1180            {
1181              os << "macro_append " + macro_name + " ";
1182              os << CmtSystem::quote (macro->resolve_macro_value (), " \t");
1183              os << "\n";
1184            }
1185        }
1186    }
1187
1188  // Write input requirements file
1189
1190  bool gen (true);
1191  //  ostringstream os;
1192  ofstream s;
1193  //  s.open (file);
1194  s.open (file, ios::in);
1195  if (s) // file already exists
1196    {
1197      //      InGen.build (constituent, os);
1198      ostringstream osn;
1199      osn << s.rdbuf ();
1200      if (os.str () == osn.str ())
1201        {
1202          //      cerr << file << " up-to-date" << endl;
1203          gen = false;
1204        }
1205    }
1206  s.clear ();
1207  s.close ();
1208  s.clear ();
1209  if (gen)
1210    {
1211      s.open (file);
1212      if (!s)
1213        {
1214          CmtError::set (CmtError::file_access_error, file);
1215          return -1;
1216        }
1217      s.exceptions (ios::failbit | ios::badbit);
1218      try
1219        {
1220          //      if (os.str ().size () != 0)
1221          //        {
1222              //  cerr << file << " contents already generated" << endl;
1223              s << os.str ();
1224              //            }
1225              //          else
1226              //            {
1227              //              InGen.build (constituent, s);
1228              //            }
1229          s.close (); // ios_base::failbit
1230        }
1231      catch (const ios::failure& e)
1232        {
1233          CmtSystem::close_ostream (NULL, file + ": " + cmt_string (e.what ()));
1234          return -1;
1235        }
1236    }
1237
1238  return 0;
1239}
1240
1241//--------------------------------------------------
1242int Generator::build_constituent_makefile (const Constituent& constituent,
1243                                           bool& dependencies,
1244                                           const cmt_string& file)
1245{
1246  const cmt_string& package = Cmt::get_current_package ();
1247
1248  switch (constituent.type)
1249    {
1250    case Application:
1251      //ApplicationContext.build (package, constituent, file);
1252      //break;
1253    case Library:
1254      LibraryContext.build (package, constituent, dependencies, file);
1255      break;
1256    case Document:
1257      DocumentContext.build (package, constituent, dependencies, file);
1258      break;
1259    }
1260
1261  return (0);
1262}
1263
1264//--------------------------------------------------
1265void Generator::build_constituent_makefile (const CmtSystem::cmt_string_vector& arguments)
1266{
1267  cmt_string name;
1268  cmt_string file;
1269
1270  if (arguments.size () == 1)
1271    {
1272      file = "";
1273      name = arguments[0];
1274    }
1275  else if (arguments.size () == 2) // arguments[0].substr (0, 5) == "-out="
1276    {
1277      cmt_string arg = arguments[0];
1278      arg.erase (0, 5);
1279      file = arg;
1280      name = arguments[1];
1281    }
1282  else
1283    {
1284      CmtMessage::error ("build constituent_makefile : wrong arguments");
1285      //      cerr << "#CMT> build constituent_makefile : wrong arguments" << endl;
1286      return;
1287    }
1288
1289  const Constituent* constituent = Constituent::find (name);
1290  if (constituent != 0)
1291    {
1292      bool dependencies (false);
1293      build_constituent_makefile (*constituent, dependencies, file);
1294    }
1295}
1296
1297//--------------------------------------------------
1298void Generator::build_default_makefile ()
1299{
1300  DefaultMakefileContext.build ();
1301}
1302
1303//--------------------------------------------------
1304void Generator::build_packages_makefile (const cmt_string& package,
1305                                         const cmt_string& file)
1306{
1307  PackagesMakefileContext.build (package, file);
1308  //  UsesMakefileContext.build (package, file);
1309}
1310
1311//--------------------------------------------------
1312void Generator::build_dependencies (const CmtSystem::cmt_string_vector& arguments)
1313{
1314  DependencyContext.build (arguments);
1315}
1316
1317//--------------------------------------------------
1318void Generator::build_prototype (const cmt_string& file_name)
1319{
1320  PrototypeContext.build (file_name);
1321}
1322
1323//--------------------------------------------------
1324void Generator::build_readme (const CmtSystem::cmt_string_vector& arguments)
1325{
1326  ReadmeContext.build (arguments);
1327}
1328
1329class WinDefAwk : public PAwk
1330{
1331public :
1332  WinDefAwk (const cmt_string& library_name)
1333  {
1334    m_name = library_name;
1335  }
1336
1337  void begin ()
1338  {
1339    cout << "LIBRARY " << m_name << endl;
1340    cout << "EXPORTS" << endl;
1341  }
1342
1343  void filter (const cmt_string& line)
1344  {
1345    if (line.find ("External") == cmt_string::npos) return;
1346    if (line.find ("??_") != cmt_string::npos)
1347      {
1348        if (line.find ("operator/=") == cmt_string::npos) return;
1349        // Keep operator /= .
1350      }
1351
1352    CmtSystem::cmt_string_vector words;
1353    CmtSystem::split (line, " \t", words);
1354    if (words.size () >= 7)
1355      {
1356        int pos = 7;
1357
1358        cmt_string& fifth_word = words[4];
1359        if (fifth_word == "()") pos = 7;
1360        else if (fifth_word == "External") pos = 6;
1361        else return;
1362
1363        cmt_string& symbol = words[pos];
1364        if (symbol[0] == '_') symbol.erase (0, 1);
1365        symbol.replace_all ("\r", "");
1366        symbol.replace_all ("\n", "");
1367
1368        if ((pos == 6) && 
1369            ((line.find(": static") != cmt_string::npos) ||
1370             (line.find("(class") != cmt_string::npos)) )
1371          {
1372            // static data members are not DATA :
1373            // extern objects are not DATA :
1374            cout << " " << symbol << " " << endl;
1375          } 
1376        else if (pos == 6)
1377          {
1378            // DATA :
1379            cout << " " << symbol << "\tDATA" << endl;
1380          } 
1381        else
1382          {
1383            // code :
1384            cout << " " << symbol << " " << endl;
1385          } 
1386      }
1387  }
1388
1389  void end ()
1390  {
1391  }
1392
1393private:
1394  cmt_string m_name;
1395};
1396
1397//--------------------------------------------------
1398//void Generator::build_windefs (const cmt_string& library_name)
1399void Generator::build_windefs (const CmtSystem::cmt_string_vector& arguments)
1400{
1401  cmt_string name;
1402  //  CmtSystem::cmt_string_vector files;
1403  cmt_string files;
1404
1405  for (int i = 0; i < arguments.size (); i++)
1406    {
1407      const cmt_string& w = arguments[i];
1408      if (w.substr (0, 6) == "-name=" || w.substr (0, 6) == "-name:" ||
1409          w.substr (0, 6) == "/name:" || w.substr (0, 6) == "/name=")
1410        w.substr (6, name);
1411      else if (w.substr (0, 1) == "@" && w.size () > 1)
1412        {
1413          cmt_string commandfile;
1414          w.substr (1, commandfile);
1415          if (!CmtSystem::test_file (commandfile))
1416            {
1417              CmtMessage::warning ("No such file `" + commandfile + "'.");
1418              continue;
1419            }
1420          cmt_string text;
1421          if (!text.read (commandfile))
1422            {
1423              CmtMessage::warning ("Could not read `" + commandfile + "'.");
1424              continue;
1425            }
1426          text.replace_all ("\r", " ");
1427          text.replace_all ("\n", " ");
1428          files += " " + text;
1429          /*
1430          CmtSystem::cmt_string_vector words;
1431          CmtSystem::split (text, " \t", words);
1432          for (int i = 0; i < words.size (); i++)
1433            {
1434              files.push_back (words[i]);
1435            }
1436          */
1437        }
1438      else
1439        files += " " + w;
1440      //        files.push_back (w);
1441    }
1442
1443  if (files.size () == 0)
1444    {
1445      CmtMessage::error ("build_windefs: no files specified");
1446      return;
1447    }
1448  if (name == "")
1449    {
1450      CmtSystem::cmt_string_vector words;
1451      CmtSystem::split (files, " \t", words);
1452      if (words.size () == 0)
1453        {
1454          CmtMessage::error ("build_windefs: no files specified");
1455          return;
1456        }
1457      cmt_string suffix;
1458      CmtSystem::get_dot_suffix (words[0], suffix);
1459      CmtSystem::basename (words[0], suffix, name);
1460    }
1461  if (name == "")
1462    {
1463      CmtMessage::error ("build_windefs: cannot determine library name");
1464      return;
1465    }
1466
1467  //  cmt_string bin;
1468
1469  //  CmtSystem::dirname (library_name, bin);
1470  //  CmtSystem::get_dot_suffix (library_name, suffix);
1471  //  CmtSystem::basename (library_name, suffix, name);
1472 
1473  //  if (!CmtSystem::cd (bin)) return;
1474 
1475  //  cmt_string command;
1476 
1477  cmt_string command ("dumpbin /symbols");
1478  //  command += library_name;
1479  /*
1480  for (int i = 0; i < files.size (); i++)
1481    {
1482      command += " " + files[i];
1483    }
1484  */
1485  command += " " + files;
1486       
1487  WinDefAwk filter (name);
1488 
1489  filter.run (command, "SECT");
1490}
1491
1492//--------------------------------------------------
1493void Packager::begin ()
1494{
1495  m_package_name = "";
1496}
1497
1498void Packager::filter (const cmt_string& line)
1499{
1500  CmtSystem::cmt_string_vector words;
1501
1502  CmtSystem::split (line, " ", words);
1503  if (words.size () > 1)
1504    {
1505      cmt_string& w = words[0];
1506
1507      if (w == "package")
1508        {
1509          m_package_name = words[1];
1510
1511          int pos = m_package_name.find (";");
1512          if (pos != cmt_string::npos) m_package_name.erase (pos);
1513          m_package_name.replace_all (".", CmtSystem::file_separator ());
1514        }
1515    }
1516}
1517
1518cmt_string& Packager::package_name ()
1519{
1520  return (m_package_name);
1521}
1522
1523//------------------------------------------------------------------------
1524InGenerator::Buffer::Buffer ()
1525  : m_initialized (false), m_usecmt (true)
1526{ }
1527
1528//------------------------------------------------------------------------
1529void InGenerator::Buffer::set_names (const CmtSystem::cmt_string_vector& names)
1530{
1531  m_names = names;
1532}
1533
1534//------------------------------------------------------------------------
1535int InGenerator::Buffer::print (ostream& s)
1536{
1537  int retval (0);
1538  retval = initialize ();
1539  if (0 > retval) return retval;
1540  s << m_buffer.str ();
1541  return 0;
1542}
1543
1544//------------------------------------------------------------------------
1545void InGenerator::Buffer::set_uses (bool usecmt)
1546{
1547  m_usecmt = usecmt;
1548}
1549
1550//------------------------------------------------------------------------
1551void InGenerator::Buffer::set_pedantic (bool pedantic)
1552{
1553  m_pedantic = pedantic;
1554}
1555
1556//------------------------------------------------------------------------
1557int InGenerator::Languages::initialize ()
1558{
1559  int errors (0);
1560  if (m_initialized) return - errors;
1561  m_initialized = true;
1562  for (int i = 0; i < m_names.size (); i++)
1563    {
1564      const cmt_string& name = m_names[i];
1565      Language& p (Language::find (name));
1566      if (Language::null () == p)
1567        {
1568          CmtError::set (CmtError::language_not_found, name);
1569          errors += 1;
1570          continue;
1571        }
1572      p.show (Requirements, m_buffer);
1573      /*
1574      if (!p->use->get_package ()->is_cmt ())
1575        p->print (Requirements, m_buffer);
1576      */
1577    }
1578  //  cerr << "Languages::initialize: " << m_buffer.str ();
1579  return - errors;
1580}
1581
1582//------------------------------------------------------------------------
1583int InGenerator::Fragments::initialize ()
1584{
1585  int errors (0);
1586  if (m_initialized) return - errors;
1587  m_initialized = true;
1588  for (int i = 0; i < m_names.size (); i++)
1589    {
1590      const cmt_string& name = m_names[i];
1591      if (Cmt::get_debug ())
1592        {
1593          cout << "InGenerator::Fragments::initialize> " << name << endl;
1594        }
1595      Fragment* fragment (Fragment::find (name));
1596      if (0 == fragment)
1597        {
1598          if (m_pedantic)
1599            {
1600              CmtError::set (CmtError::fragment_not_found, name + " (standard)");
1601              errors += 1;
1602            }
1603          else
1604            {
1605              CmtMessage::warning
1606                (CmtError::get_error_name (CmtError::fragment_not_found)
1607                 + ": " + name + " (standard)");
1608            }
1609          continue;
1610        }
1611      if (m_usecmt || !fragment->use->get_package ()->is_cmt ())
1612        if (1 != fragment->print (Requirements, m_buffer))
1613          {
1614            if (m_pedantic)
1615              {
1616                CmtError::set (CmtError::fragment_not_found, name + " (standard)");
1617                errors += 1;
1618              }
1619            else
1620              {
1621                CmtMessage::warning
1622                  (CmtError::get_error_name (CmtError::fragment_not_found)
1623                   + ": " + name + " (standard)");
1624              }
1625            continue;
1626          }
1627    }
1628  //  cerr << "initialize: " << m_buffer.str ();
1629  return - errors;
1630}
1631
1632//------------------------------------------------------------------------
1633InGenerator::InGenerator (bool usecmt, bool pedantic)
1634  : m_usecmt (usecmt), m_pedantic (pedantic)
1635{
1636  m_pedantic = (0 != CmtSystem::getenv ("CMTPEDANTIC").size () ||
1637                0 != CmtSystem::getenv ("PEDANTIC").size ());
1638
1639  m_common.set_pedantic (m_pedantic);
1640  m_application.set_pedantic (m_pedantic);
1641  m_application_library.set_pedantic (m_pedantic);
1642  m_library.set_pedantic (m_pedantic);
1643  m_document.set_pedantic (m_pedantic);
1644  m_languages.set_pedantic (m_pedantic);
1645
1646  CmtSystem::cmt_string_vector common;
1647  common.push_back ("make_header");
1648  common.push_back ("dependencies");
1649  common.push_back ("cleanup_header");
1650  m_common.set_names (common);
1651  m_common.set_uses (usecmt);
1652
1653  CmtSystem::cmt_string_vector application;
1654  application.push_back ("java_header");
1655  application.push_back ("application_header");
1656  application.push_back ("application");
1657  application.push_back ("check_java");
1658  application.push_back ("cleanup_application");
1659  application.push_back ("cleanup_objects");
1660  application.push_back ("check_application");
1661
1662  CmtSystem::cmt_string_vector application_library;
1663  application_library.push_back ("protos_header");
1664  application_library.push_back ("buildproto");
1665  application_library.push_back ("dependencies_and_triggers");
1666  application_library.push_back ("java");
1667  application_library.push_back ("java_copy");
1668  application_library.push_back ("cleanup");
1669  application_library.push_back ("cleanup_java");
1670  m_application_library.set_names (application_library);
1671  m_application_library.set_uses (usecmt);
1672
1673  CmtSystem::cmt_string_vector library;
1674  library.push_back ("jar_header");
1675  library.push_back ("library_header");
1676  library.push_back ("jar");
1677  library.push_back ("library_no_share");
1678  library.push_back ("library_no_static");
1679  library.push_back ("library");
1680  library.push_back ("cleanup_library");
1681
1682  CmtSystem::cmt_string_vector languages;
1683  Language::LanguageVector& Languages = Language::languages ();
1684  for (int n = 0; n < Languages.size (); n++)
1685    {
1686      Language& language = Languages[n];
1687      //language.setup_fragments ();
1688      application.push_back (language.fragment_name); //application.name ();
1689      if (!(language == "java"))
1690        library.push_back (language.fragment_name + "_library"); //library.name ();
1691      if (m_usecmt || !language.m_use->get_package ()->is_cmt ())
1692//       if (!language.m_use->get_package ()->is_cmt ())
1693        {
1694          languages.push_back (language.m_name);
1695        }
1696      else if (language.dependencies_options () !=
1697          language.dependencies_options_expanded ())
1698        {
1699          languages.push_back (language.m_name);
1700        }
1701    }
1702  m_languages.set_names (languages);
1703  m_languages.set_uses (usecmt);
1704  m_application.set_names (application);
1705  m_application.set_uses (usecmt);
1706  m_library.set_names (library);
1707  m_library.set_uses (usecmt);
1708 
1709  CmtSystem::cmt_string_vector document;
1710  document.push_back ("document_header");
1711  document.push_back ("dependency");
1712  m_document.set_names (document);
1713  m_document.set_uses (usecmt);
1714}
1715
1716//------------------------------------------------------------------------
1717int InGenerator::build (const Constituent& constituent, ostream& s)
1718{
1719  int retval (0);
1720
1721  constituent.show (s);
1722  retval += m_common.print (s);
1723
1724  switch (constituent.type)
1725    {
1726    case Application:
1727      retval += m_application.print (s);
1728      retval += m_application_library.print (s);
1729      retval += m_languages.print (s);
1730      break;
1731    case Library:
1732      retval += m_application_library.print (s);
1733      retval += m_library.print (s);
1734      retval += m_languages.print (s);
1735      break;
1736    case Document:
1737      Fragment* fragment (Fragment::find (constituent.generator));
1738      if (Cmt::get_debug ())
1739        {
1740          cout << "InGenerator::build> " << constituent.generator
1741               << " |name> " << constituent.name << endl;
1742        }
1743      if (0 == fragment)
1744        {
1745          CmtError::set (CmtError::fragment_not_found, constituent.generator
1746                         + " (document " + constituent.name + ")");
1747          return retval -= 1;
1748        }
1749      if (m_usecmt || !fragment->use->get_package ()->is_cmt ())
1750        if (1 != fragment->print (Requirements, s))
1751          {
1752            CmtError::set (CmtError::fragment_not_found, constituent.generator
1753                           + " (document " + constituent.name + ")");
1754            return retval -= 1;
1755          }
1756      if (0 != fragment->header.size ())
1757        {
1758          if (Cmt::get_debug ())
1759            {
1760              cout << "InGenerator::build> " << fragment->header
1761                   << " |name> " << constituent.name << endl;
1762            }
1763          Fragment* header (Fragment::find (fragment->header));
1764          if (0 == header)
1765            {
1766              CmtError::set (CmtError::fragment_not_found, fragment->header
1767                             + " (document " + constituent.name + ")");
1768              return retval -= 1;
1769            }
1770          //      if (header->use != fragment->use &&
1771          if (m_usecmt || !header->use->get_package ()->is_cmt ())
1772            if (1 != header->print (Requirements, s))
1773              {
1774                CmtError::set (CmtError::fragment_not_found, fragment->header
1775                               + " (document " + constituent.name + ")");
1776                return retval -= 1;
1777              }
1778        }
1779      if (0 != fragment->trailer.size ())
1780        {
1781          if (Cmt::get_debug ())
1782            {
1783              cout << "InGenerator::build> " << fragment->trailer
1784                   << " |name> " << constituent.name << endl;
1785            }
1786          Fragment* trailer (Fragment::find (fragment->trailer));
1787          if (0 == trailer)
1788            {
1789              CmtError::set (CmtError::fragment_not_found, fragment->trailer
1790                             + " (document " + constituent.name + ")");
1791              return retval -= 1;
1792            }
1793          //      if (trailer->use != fragment->use &&
1794          if (m_usecmt || !trailer->use->get_package ()->is_cmt ())
1795            if (1 != trailer->print (Requirements, s))
1796              {
1797                CmtError::set (CmtError::fragment_not_found, fragment->trailer
1798                               + " (document " + constituent.name + ")");
1799                return retval -= 1;
1800              }
1801        }
1802      retval += m_document.print (s);
1803      break;
1804    }
1805
1806  if (m_pedantic)
1807    return retval;
1808  else
1809    return 0;
1810}
1811//------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.