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

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

merge -r 618:627 HEAD

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