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

Last change on this file since 628 was 628, checked in by rybkin, 11 years ago

See C.L. 499

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