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

Last change on this file since 595 was 595, checked in by rybkin, 12 years ago

See C.L. 472

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