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

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

See C.L. 524

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