source: CMT/v1r12p20020606/src/cmt_generator.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 79.4 KB
Line 
1#include <errno.h>
2#include <stdio.h>
3
4#ifndef WIN32
5#include <unistd.h>
6#endif
7
8#include "cmt_use.h"
9#include "cmt_fragment.h"
10#include "cmt_symbol.h"
11#include "cmt_system.h"
12#include "cmt.h"
13#include "cmt_deps_builder.h"
14#include "cmt_generator.h"
15#include "cmt_constituent.h"
16#include "cmt_language.h"
17#include "cmt_awk.h"
18
19static Variable DOCPATH            ("DOCPATH");
20static Variable PACKAGEPATH        ("PACKAGEPATH");
21static Variable PACKAGEPREFIX      ("PACKAGEPREFIX");
22static Variable PACKAGE            ("PACKAGE");
23static Variable VERSION            ("VERSION");
24static Variable MGRSTYLE           ("MGRSTYLE");
25static Variable TITLE              ("TITLE");
26static Variable GROUP              ("GROUP");
27static Variable CONSTITUENT        ("CONSTITUENT");
28static Variable CONSTITUENTSUFFIX  ("CONSTITUENTSUFFIX");
29static Variable LIBRARYSUFFIX      ("LIBRARYSUFFIX");
30static Variable USER               ("USER");
31static Variable DATE               ("DATE");
32static Variable PROTOTARGET        ("PROTOTARGET");
33static Variable OBJS               ("OBJS");
34static Variable CLASSES            ("CLASSES");
35static Variable PROTOSTAMPS        ("PROTOSTAMPS");
36static Variable NAME               ("NAME");
37static Variable FILEPATH           ("FILEPATH");
38static Variable FILESUFFIX         ("FILESUFFIX");
39static Variable SUFFIX             ("SUFFIX");
40static Variable FILENAME           ("FILENAME");
41static Variable LINKMACRO          ("LINKMACRO");
42static Variable LINE               ("LINE");
43static Variable ADDINCLUDE         ("ADDINCLUDE");
44static Variable FULLNAME           ("FULLNAME");
45static Variable OUTPUTNAME         ("OUTPUTNAME");
46static Variable ALLOS9SOURCES      ("ALLOS9SOURCES");
47static Variable NODEBUGUSELINKOPTS ("NODEBUGUSELINKOPTS");
48static Variable DEBUGUSELINKOPTS   ("DEBUGUSELINKOPTS");
49static Variable USEINCLUDES        ("USEINCLUDES");
50//------------------------------------------------------------------------
51
52//------------------------------------------------------------------------
53class SourceFile
54{
55public:
56  void set (const cmt_string name, Language& language, const cmt_string output)
57  {
58    m_name = name;
59    m_language = &language;
60    m_output = output;
61
62    char sep = CmtSystem::file_separator ();
63    if (sep == '/') m_name.replace_all ("\\", sep);
64    else m_name.replace_all ("/", sep);
65  }
66
67  cmt_string name () const
68  {
69    return (m_name);
70  }
71
72  Language& language () const
73  {
74    return (*m_language);
75  }
76
77  cmt_string output () const
78  {
79    return (m_output);
80  }
81
82private:
83  cmt_string m_name;
84  Language* m_language;
85  cmt_string m_output;
86};
87//------------------------------------------------------------------------
88
89//------------------------------------------------------------------------
90class MakefileGenerator
91{
92public:
93
94  void analyze_file (const Constituent& constituent,
95                     const cmt_string& file);
96  void analyze_document_file (const cmt_string& file,
97                              const cmt_string& constituent_name,
98                              const cmt_string& output_suffix);
99  void reset ();
100
101  void prepare_proto_file (const cmt_string& file);
102  void proto_file_action (const cmt_string& file, const Constituent& constituent);
103  void module_file_action (SourceFile& file, const Constituent& constituent);
104  void java_file_action (SourceFile& file, const Constituent& constituent);
105
106  void fill_outputs ();
107
108  void build_application_makefile (const cmt_string& package,
109                                   const Constituent& constituent);
110
111  void build_library_makefile (const cmt_string& package,
112                               const Constituent& constituent);
113
114  void build_document_makefile (const cmt_string& package,
115                                const Constituent& constituent);
116
117  void prepare_use_context ();
118
119  void set_full_name (cmt_string& full_name, cmt_string& file);
120
121  cmt_string PACKINCLUDES;
122  bool PACKOS9;
123
124  cmt_string GENERATOR;
125  bool is_library;
126  bool is_application;
127  bool is_document;
128  cmt_string srcdir;
129  cmt_string docdir;
130  cmt_string cmtdir;
131  cmt_string incdir;
132  cmt_string msdevdir;
133  cmt_string src;
134  cmt_string doc;
135  cmt_string inc;
136  cmt_string mgr;
137  cmt_string cmt;
138  cmt_string protos;
139  cmt_string protonames;
140  cmt_string os9sources;
141
142  cmt_vector<SourceFile> source_files;
143
144  FILE* output_file;
145
146  DepsBuilder deps_builder;
147};
148//------------------------------------------------------------------------
149
150//------------------------------------------------------------------------
151static MakefileGenerator Context;
152
153static FragmentHandle buildproto_fragment ("buildproto");
154static FragmentHandle dependencies_fragment ("dependencies");
155static FragmentHandle dependencies_and_triggers_fragment ("dependencies_and_triggers");
156
157static FragmentHandle make_header_fragment ("make_header");
158static FragmentHandle library_header_fragment ("library_header");
159static FragmentHandle application_header_fragment ("application_header");
160static FragmentHandle document_header_fragment ("document_header");
161static FragmentHandle java_header_fragment ("java_header");
162static FragmentHandle jar_header_fragment ("jar_header");
163static FragmentHandle protos_header_fragment ("protos_header");
164static FragmentHandle library_fragment ("library");
165static FragmentHandle library_no_share_fragment ("library_no_share");
166static FragmentHandle application_fragment ("application");
167static FragmentHandle jar_fragment ("jar");
168static FragmentHandle java_fragment ("java");
169static FragmentHandle cleanup_header_fragment ("cleanup_header");
170static FragmentHandle cleanup_fragment ("cleanup");
171static FragmentHandle cleanup_library_fragment ("cleanup_library");
172static FragmentHandle cleanup_application_fragment ("cleanup_application");
173static FragmentHandle cleanup_java_fragment ("cleanup_java");
174static FragmentHandle cleanup_objects_fragment ("cleanup_objects");
175
176static FragmentHandle dsw_header_fragment ("dsw_header");
177static FragmentHandle dsw_project_fragment ("dsw_project");
178static FragmentHandle dsw_all_project_header_fragment ("dsw_all_project_header");
179static FragmentHandle dsw_all_project_dependency_fragment ("dsw_all_project_dependency");
180static FragmentHandle dsw_all_project_trailer_fragment ("dsw_all_project_trailer");
181static FragmentHandle dsw_trailer_fragment ("dsw_trailer");
182
183static FragmentHandle dsp_all_fragment ("dsp_all");
184static FragmentHandle dsp_library_header_fragment ("dsp_library_header");
185//static FragmentHandle dsp_shared_library_header_fragment ("dsp_shared_library_header");
186static FragmentHandle dsp_application_header_fragment ("dsp_application_header");
187static FragmentHandle dsp_windows_header_fragment ("dsp_windows_header");
188static FragmentHandle dsp_contents_fragment ("dsp_contents");
189static FragmentHandle dsp_trailer_fragment ("dsp_trailer");
190
191static FragmentHandle make_setup_header_fragment ("make_setup_header");
192static FragmentHandle make_setup_fragment ("make_setup");
193
194static FragmentHandle constituents_header_fragment ("constituents_header");
195static FragmentHandle group_fragment ("group");
196static FragmentHandle constituent_fragment ("constituent");
197static FragmentHandle constituents_trailer_fragment ("constituents_trailer");
198
199static FragmentHandle readme_header_fragment ("readme_header");
200static FragmentHandle readme_fragment ("readme");
201static FragmentHandle readme_doc_fragment ("readme_doc");
202static FragmentHandle readme_use_fragment ("readme_use");
203static FragmentHandle readme_trailer_fragment ("readme_trailer");
204
205static FragmentHandle check_application_fragment ("check_application");
206static FragmentHandle check_java_fragment ("check_java");
207static FragmentHandle check_application_header_fragment ("check_application_header");
208//------------------------------------------------------------------------
209
210//--------------------------------------------------
211class Packager : public FAwk
212{
213public:
214  void begin ();
215  void filter (const cmt_string& line);
216  cmt_string& package_name ();
217private:
218  cmt_string m_package_name;
219};
220//--------------------------------------------------
221
222//--------------------------------------------------
223static void filter_paths (cmt_string& text)
224{
225  static CmtSystem::cmt_string_vector ps;
226
227  CmtSystem::split (text, " ", ps);
228
229  text = "";
230
231  for (int i = 0; i < ps.size (); i++)
232    {
233      cmt_string& s = ps[i];
234
235      CmtSystem::compress_path (s);
236
237        //cout << "   filter_paths " << s << endl;
238
239      if (i > 0) text += " ";
240      text += s;
241    }
242
243  text.replace_all ("./../src/", "$(src)");
244  text.replace_all (".\\..\\src\\", "$(src)");
245  text.replace_all ("../src/", "$(src)");
246  text.replace_all ("..\\src\\", "$(src)");
247  text.replace_all ("../doc/", "$(doc)");
248  text.replace_all ("..\\doc\\", "$(doc)");
249  text.replace_all ("$(src)$(src)", "$(src)");
250}
251
252static void get_all_files (const cmt_string& full_name, 
253                           CmtSystem::cmt_string_vector& files)
254{
255  static cmt_string suffix;
256  static cmt_string name;
257
258  suffix = "";
259  name = "";
260
261  files.clear ();
262
263  CmtSystem::get_dot_suffix (full_name, suffix);
264
265  if (full_name.find ('*') != cmt_string::npos)
266    {
267      CmtSystem::scan_dir (full_name, files);
268
269      if (Cmt::get_debug ())
270        {
271          cout << "CMT> full_name=" << full_name <<
272            " pwd=" << CmtSystem::pwd () << endl;
273          cout << "CMT> files.size=" <<  files.size () << endl;
274        }
275
276      for (int j = 0; j < files.size (); j++)
277        {
278          cmt_string& n = files[j];
279          static cmt_string s;
280
281          CmtSystem::get_dot_suffix (n, s);
282          if (s != suffix) 
283            {
284              n = "";
285            }
286        }
287    }
288  else
289    {
290      cmt_string& n = files.add ();
291
292      n = full_name;
293    }
294}
295
296//--------------------------------------------------
297
298//--------------------------------------------------
299void MakefileGenerator::analyze_file (const Constituent& constituent,
300                                      const cmt_string& file)
301{
302  static cmt_string suffix;
303  static cmt_string name;
304  static cmt_string obj;
305
306  obj = file;
307
308  if (Cmt::get_debug ())
309    {
310      cout << "MakefileGenerator::analyze_file> constituent=" << 
311          constituent.name <<
312          " file=" << file << endl;
313    }
314
315  CmtSystem::get_suffix (file, suffix);
316  CmtSystem::basename (file, suffix, name);
317
318  Language& language = Language::find_with_suffix (suffix);
319
320  if (LINKMACRO == "")
321    {
322      LINKMACRO = language.linker;
323    }
324
325  if (language == "java")
326    {
327      static Packager packager;
328     
329      obj  = "$(javabin)";
330     
331      packager.run (file);
332      if (packager.package_name () != "")
333        {
334          obj += packager.package_name ();
335          obj += CmtSystem::file_separator ();
336        }
337     
338      obj += name;
339      obj += ".class";
340    }
341  else if (language != Language::null ())
342    {
343      obj  = "$(bin)";
344      if (Cmt::build_nmake ()) obj +=  CONSTITUENT;
345      if (Cmt::build_nmake ()) obj +=  CmtSystem::file_separator ();
346      obj += name;
347      obj += language.output_suffix;
348      obj += constituent.suffix;
349      if (Cmt::build_nmake ()) obj += ".obj";
350      else obj += ".o";
351 
352      for (int i = 0; i < language.extra_output_suffixes.size (); i++)
353        {
354          cmt_string& extra_suffix = language.extra_output_suffixes[i];
355
356          obj += " $(bin)";
357          obj += name;
358          obj += extra_suffix;
359          obj += language.output_suffix;
360          obj += constituent.suffix;
361          if (Cmt::build_nmake ()) obj += ".obj";
362          else obj += ".o";
363        }
364    }
365  else
366    {
367      cout << "#CMT> analyze_file file=" << file << " no language" << endl;
368    }
369
370  if (Cmt::get_debug ())
371    {
372      cout << "MakefileGenerator::analyze_file> constituent=" << 
373          constituent.name <<
374          " obj=" << obj << endl;
375    }
376
377  SourceFile& source = source_files.add ();
378  source.set (file, language, obj);
379}
380
381//--------------------------------------------------
382void MakefileGenerator::analyze_document_file (const cmt_string& file,
383                                               const cmt_string& constituent_name,
384                                               const cmt_string& output_suffix)
385{
386  static cmt_string output_dir;
387  static cmt_string suffix;
388  static cmt_string name;
389  static cmt_string obj;
390
391  CmtSystem::dirname (file, output_dir);
392  output_dir += CmtSystem::file_separator ();
393
394  filter_paths (output_dir);
395
396  CmtSystem::get_suffix (file, suffix);
397  CmtSystem::basename (file, suffix, name);
398
399  //obj = output_dir;
400  obj = "$(";
401  obj += constituent_name;
402  obj += "_output)";
403  obj += name;
404  obj += output_suffix;
405
406  SourceFile& source = source_files.add ();
407  source.set (file, Language::null (), obj);
408}
409
410//--------------------------------------------------
411void MakefileGenerator::reset ()
412{
413  DOCPATH = "";
414  PACKAGEPATH = "";
415  PACKAGEPREFIX = "";
416  PACKAGE = "";
417  VERSION = "";
418  MGRSTYLE = "";
419  TITLE = "";
420  GROUP = "";
421  CONSTITUENT = "";
422  CONSTITUENTSUFFIX = "";
423  LIBRARYSUFFIX = "";
424  USER = "";
425  DATE = "";
426  PROTOTARGET = "";
427  OBJS = "";
428  CLASSES = "";
429  PROTOSTAMPS = "";
430  NAME = "";
431  FILEPATH = "";
432  FILESUFFIX = "";
433  SUFFIX = "";
434  FILENAME = "";
435  LINKMACRO = "";
436  LINE = "";
437  ADDINCLUDE = "";
438  FULLNAME = "";
439  OUTPUTNAME = "";
440  ALLOS9SOURCES = "";
441  NODEBUGUSELINKOPTS = "";
442  DEBUGUSELINKOPTS = "";
443  USEINCLUDES = "";
444
445  PACKINCLUDES = "";
446  PACKOS9      = false;
447  GENERATOR    = "";
448
449  is_library     = false;
450  is_application = false;
451  is_document    = false;
452  srcdir       = "";
453  docdir       = "";
454  cmtdir       = "";
455  incdir       = "";
456  src          = "$(src)";
457  doc          = "$(doc)";
458  inc          = "$(inc)";
459  mgr          = "$(mgr)";
460  cmt          = "$(cmt)";
461  protos       = "";
462  protonames   = "";
463  os9sources   = "";
464
465  source_files.clear ();
466
467  buildproto_fragment.reset ();
468  dependencies_fragment.reset ();
469  dependencies_and_triggers_fragment.reset ();
470
471  make_header_fragment.reset ();
472  library_header_fragment.reset ();
473  application_header_fragment.reset ();
474  document_header_fragment.reset ();
475  java_header_fragment.reset ();
476  jar_header_fragment.reset ();
477  protos_header_fragment.reset ();
478  library_fragment.reset ();
479  library_no_share_fragment.reset ();
480  jar_fragment.reset ();
481  application_fragment.reset ();
482  java_fragment.reset ();
483  cleanup_header_fragment.reset ();
484  cleanup_fragment.reset ();
485  cleanup_library_fragment.reset ();
486  cleanup_application_fragment.reset ();
487  cleanup_java_fragment.reset ();
488  cleanup_objects_fragment.reset ();
489
490  dsw_header_fragment.reset ();
491  dsw_project_fragment.reset ();
492  dsw_all_project_header_fragment.reset ();
493  dsw_all_project_dependency_fragment.reset ();
494  dsw_all_project_trailer_fragment.reset ();
495  dsw_trailer_fragment.reset ();
496
497  dsp_all_fragment.reset ();
498  dsp_library_header_fragment.reset ();
499  //dsp_shared_library_header_fragment.reset ();
500  dsp_application_header_fragment.reset ();
501  dsp_windows_header_fragment.reset ();
502  dsp_contents_fragment.reset ();
503  dsp_trailer_fragment.reset ();
504
505  make_setup_header_fragment.reset ();
506  make_setup_fragment.reset ();
507
508  constituents_header_fragment.reset ();
509  group_fragment.reset ();
510  constituent_fragment.reset ();
511  constituents_trailer_fragment.reset ();
512
513  readme_header_fragment.reset ();
514  readme_fragment.reset ();
515  readme_doc_fragment.reset ();
516  readme_use_fragment.reset ();
517  readme_trailer_fragment.reset ();
518
519  check_application_fragment.reset ();
520  check_java_fragment.reset ();
521  check_application_header_fragment.reset ();
522
523  Language::setup_all_fragments ();
524
525  CmtSystem::cd (Cmt::get_current_dir ());
526
527  cmt_string branch = CmtSystem::current_branch ();
528
529  if ((branch == "mgr") || (branch == "cmt"))
530    {
531      if (CmtSystem::test_directory ("../src"))
532        {
533          srcdir = "..";
534          srcdir += CmtSystem::file_separator ();
535          srcdir += "src";
536          srcdir += CmtSystem::file_separator ();
537        }
538      else
539        {
540          srcdir = "";
541        }
542
543      if (CmtSystem::test_directory ("../doc"))
544        {
545          docdir = "..";
546          docdir += CmtSystem::file_separator ();
547          docdir += "doc";
548          docdir += CmtSystem::file_separator ();
549        }
550      else
551        {
552          docdir = "";
553        }
554
555      if (CmtSystem::test_directory ("../cmt"))
556        {
557          cmtdir = "..";
558          cmtdir += CmtSystem::file_separator ();
559          cmtdir += "cmt";
560          cmtdir += CmtSystem::file_separator ();
561        }
562      else if (CmtSystem::test_directory ("../mgr"))
563        {
564          cmtdir = "..";
565          cmtdir += CmtSystem::file_separator ();
566          cmtdir += "mgr";
567          cmtdir += CmtSystem::file_separator ();
568        }
569      else
570        {
571          cmtdir = CmtSystem::pwd ();
572          cmtdir += CmtSystem::file_separator ();
573        }
574
575      if (CmtSystem::test_directory ("../src"))
576        {
577          incdir = "..";
578          incdir += CmtSystem::file_separator ();
579          incdir += "src";
580          incdir += CmtSystem::file_separator ();
581        }
582      else
583        {
584          incdir = "";
585        }
586
587#ifdef WIN32
588      msdevdir = "..";
589      msdevdir += CmtSystem::file_separator ();
590      msdevdir += "Visual";
591
592      if (!CmtSystem::test_directory (msdevdir))
593        {
594          CmtSystem::mkdir (msdevdir);
595        }
596
597      msdevdir += CmtSystem::file_separator ();
598#endif
599
600    }
601  else
602    {
603      srcdir = ".";
604      srcdir += CmtSystem::file_separator ();
605      docdir = ".";
606      docdir += CmtSystem::file_separator ();
607      cmtdir = CmtSystem::pwd ();
608      cmtdir += CmtSystem::file_separator ();
609      incdir = ".";
610      incdir += CmtSystem::file_separator ();
611#ifdef WIN32
612      msdevdir = ".";
613      msdevdir += CmtSystem::file_separator ();
614#endif
615    }
616}
617
618//--------------------------------------------------
619void MakefileGenerator::build_application_makefile (const cmt_string& package,
620                                                    const Constituent& constituent)
621{
622  build_library_makefile (package, constituent);
623}
624
625//--------------------------------------------------
626void MakefileGenerator::prepare_proto_file (const cmt_string& file)
627{
628  static cmt_string name;
629  static cmt_string pp;
630
631  CmtSystem::name (file, name);
632
633  if (CmtSystem::test_file (file))
634    {
635      pp  = incdir;
636      pp += name;
637      pp += ".pp";
638
639      if (!CmtSystem::test_file (pp))
640        {
641          //Generator::build_prototype (file);
642        }
643    }
644
645  protos += " ";
646  protos += inc;
647  protos += name;
648  protos += ".ph";
649
650  protonames += " ";
651  protonames += name;
652  protonames += ".ph";
653
654  PROTOSTAMPS += " ";
655  PROTOSTAMPS += inc;
656  PROTOSTAMPS += name;
657  PROTOSTAMPS += ".pp";
658}
659
660//--------------------------------------------------
661void MakefileGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent)
662{
663  static cmt_string suffix;
664
665  CmtSystem::dirname (file, FILEPATH.value);
666  if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
667
668  filter_paths (FILEPATH.value);
669
670  CmtSystem::basename (file, FILENAME.value);
671  CmtSystem::get_dot_suffix (FILENAME, suffix);
672
673  CmtSystem::basename (FILENAME, suffix, NAME.value);
674
675  buildproto_fragment.copy (output_file, constituent.variables, 3, &NAME, &FILEPATH, &FILENAME);
676}
677
678//--------------------------------------------------
679void MakefileGenerator::module_file_action (SourceFile& file, const Constituent& constituent)
680{
681  cmt_string name = file.name ();
682  Language& language = file.language ();
683
684  static cmt_string suffix;
685  static cmt_string prefix;
686  static cmt_string preproc;
687
688  FULLNAME = name;
689
690  CmtSystem::get_dot_suffix (name, suffix);
691
692  CmtSystem::basename (name, suffix, NAME.value);
693
694  CmtSystem::dirname (name, prefix);
695  CmtSystem::basename (name, FILENAME.value);
696
697  FragmentHandle* fragment;
698
699  if (language != Language::null ())
700    {
701      preproc = language.preprocessor_command;
702      fragment = (is_library) ? &(language.library) : &(language.application);
703    }
704  else
705    {
706      //
707      // What happens when the language is not known???
708      //
709      //
710      preproc = "-I";
711      fragment = 0;
712    }
713
714  if ((prefix == "../src") || (prefix == "..\\src"))
715    {
716      ADDINCLUDE = "";
717    }
718  else if (prefix != "")
719    {
720      ADDINCLUDE  = preproc;
721      ADDINCLUDE += prefix;
722    }
723
724  if (!CmtSystem::test_file (name))
725    {
726      cout << "#CMT> Warning : Source file " << name << " not found" << endl;
727    }
728
729  FILEPATH = prefix;
730  if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
731  filter_paths (FILEPATH.value);
732
733  LINE = FULLNAME.value;
734  LINE += " ";
735
736  filter_paths (FULLNAME.value);
737  filter_paths (LINE.value);
738
739  CmtSystem::get_suffix (name, FILESUFFIX.value);
740
741  if (fragment != 0)
742    {
743      fragment->copy (output_file, constituent.variables, 10,
744                      &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME, &NAME, &LINE,
745                      &ADDINCLUDE, &FULLNAME, &FILEPATH, &FILESUFFIX, &PACKAGE);
746    }
747
748  if (PACKOS9)
749    {
750      os9sources += LINE;
751      os9sources += " ";
752    }
753}
754
755//--------------------------------------------------
756void MakefileGenerator::java_file_action (SourceFile& file, const Constituent& constituent)
757{
758  static cmt_string suffix;
759
760  FULLNAME = file.name ();
761  OUTPUTNAME = file.output ();
762
763  CmtSystem::get_dot_suffix (FULLNAME, suffix);
764 
765  CmtSystem::basename (FULLNAME, suffix, NAME.value);
766  CmtSystem::basename (FULLNAME, FILENAME.value);
767 
768  if (CmtSystem::test_file (FULLNAME))
769    {
770      java_fragment.copy (output_file, constituent.variables, 5, &NAME,
771                          &FULLNAME, &OUTPUTNAME,
772                          &CONSTITUENT, &CONSTITUENTSUFFIX);
773    }
774  else
775    {
776      cout << "#CMT> Warning : file " << FULLNAME << " not found" << endl;
777    }
778}
779
780//--------------------------------------------------
781void MakefileGenerator::fill_outputs ()
782{
783  bool first = true;
784
785  OBJS = "";
786
787  for (int i = 0; i < source_files.size (); i++)
788    {
789      const SourceFile& file = source_files[i];
790      const cmt_string output = file.output ();
791
792      if (output != "")
793        {
794          if (first)
795            {
796              first = false;
797            }
798          else
799            {
800              OBJS += " ";
801            }
802
803          OBJS += output;
804        }
805
806      if (Cmt::get_debug ())
807        {
808          cout << "MakefileGenerator::fill_outputs> output=" << output << " OBJS=" << OBJS << endl;
809        }
810
811    }
812
813  if (Cmt::get_debug ())
814    {
815      cout << "MakefileGenerator::fill_outputs> OBJS=" << OBJS << endl;
816    }
817
818}
819
820//--------------------------------------------------
821void MakefileGenerator::build_library_makefile (const cmt_string& package,
822                                                const Constituent& constituent)
823{
824  static cmt_string lib;
825  static cmt_string allsources;
826  static cmt_string file;
827  static cmt_string full_name;
828  static cmt_string compressed_name;
829  static cmt_string suffix;
830  int i;
831  bool need_prototypes;
832
833  source_files.clear ();
834
835  need_prototypes = constituent.need_prototypes;
836
837  cout << TITLE << " " << CONSTITUENT << endl;
838
839  lib  = "$(";
840  lib += CONSTITUENT;
841  lib += "lib)";
842
843  //
844  // Prepare the include paths
845  //
846
847  const CmtSystem::cmt_string_vector& includes = constituent.includes;
848
849  for (i = 0; i < includes.size (); i++)
850    {
851      const cmt_string& subdir = includes[i];
852
853      PACKINCLUDES += " -I";
854      PACKINCLUDES += subdir;
855    }
856
857  //
858  // Scan the sources.
859  //
860
861  const CmtSystem::cmt_string_vector& sources = constituent.modules;
862
863  for (i = 0; i < sources.size (); i++)
864    {
865      file = sources[i];
866
867      set_full_name (full_name, file);
868      if (full_name == "") continue;
869
870      CmtSystem::compress_path (full_name, compressed_name);
871      full_name = compressed_name;
872
873      static CmtSystem::cmt_string_vector files;
874
875      get_all_files (full_name, files);
876
877      for (int j = 0; j < files.size (); j++)
878        {
879          const cmt_string& name = files[j];
880
881          if (name != "") 
882            {
883              analyze_file (constituent, name);
884            }
885        }
886    }
887
888  fill_outputs ();
889
890  prepare_use_context ();
891
892  DATE = CmtSystem::now ();
893  USER = CmtSystem::user ();
894  PACKAGE = package;
895
896  make_header_fragment.copy (output_file, constituent.variables, 6, 
897                             &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX,
898                             &USER, &DATE, &PACKAGE);
899
900  if (need_prototypes)
901    {
902      need_prototypes = false;
903
904      for (i = 0; i < source_files.size (); i++)
905        {
906          const SourceFile& file = source_files[i];
907          Language& language = file.language ();
908          if (language.prototypes)
909            {
910              need_prototypes = true;
911              break;
912            }
913        }
914    }
915
916  //-------------------------------------------
917  //
918  // Specific targets (application, library or java)
919  // Prepare in case prototype files are needed
920  //
921  //-------------------------------------------
922
923  PROTOTARGET = "";
924
925  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
926  if (need_prototypes)
927    {
928      PROTOTARGET = CONSTITUENT;
929      PROTOTARGET += "PROTOS";
930    }
931
932  if (LINKMACRO == "java")
933    {
934      if (is_library)
935        {
936          jar_header_fragment.copy (output_file, constituent.variables, 3, 
937                                    &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
938        }
939      else
940        {
941          java_header_fragment.copy (output_file, constituent.variables, 3, 
942                                     &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
943        }
944    }
945  else
946    {
947      if (is_library)
948        {
949          library_header_fragment.copy (output_file, constituent.variables, 3,
950                                        &CONSTITUENT,
951                                        &CONSTITUENTSUFFIX,
952                                        &PROTOTARGET);
953        }
954      else
955        {
956          application_header_fragment.copy (output_file, constituent.variables, 3,
957                                            &CONSTITUENT, &CONSTITUENTSUFFIX, 
958                                            &PROTOTARGET);
959        }
960    }
961
962
963  //----------------------------------------------------
964  //
965  // Preparing prototype files.
966  //
967  //----------------------------------------------------
968
969  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
970  if (need_prototypes)
971    {
972      for (i = 0; i < source_files.size (); i++)
973        {
974          const SourceFile& file = source_files[i];
975          Language& language = file.language ();
976          if (language.prototypes)
977            {
978              prepare_proto_file (file.name ());
979            }
980        }
981
982      if (PROTOSTAMPS != "")
983        {
984          protos_header_fragment.copy (output_file, constituent.variables, 3, 
985                                       &CONSTITUENT, &CONSTITUENTSUFFIX, &PROTOSTAMPS);
986        }
987
988      if (protonames != "")
989        {
990          for (i = 0; i < source_files.size (); i++)
991            {
992              const SourceFile& file = source_files[i];
993              Language& language = file.language ();
994              if (language.prototypes)
995                {
996                  proto_file_action (file.name (), constituent);
997                }
998            }
999        }
1000    }
1001
1002  //----------------------------------------------------
1003  //
1004  // Preparing the library.
1005  //
1006  //----------------------------------------------------
1007
1008  if (OBJS != "")
1009    {
1010      if (LINKMACRO == "java")
1011        {
1012          if (is_library)
1013            {
1014              cmt_string classes = OBJS.value;
1015
1016              classes.replace_all ("$(javabin)", "");
1017              classes.replace_all (srcdir.c_str (), "");
1018
1019              CLASSES = classes;
1020
1021              jar_fragment.copy (output_file, constituent.variables, 4, 
1022                                 &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS, &CLASSES);
1023            }
1024        }
1025      else
1026        {
1027          if (is_library)
1028            {
1029              if (constituent.no_share)
1030                {
1031                  library_no_share_fragment.copy (output_file, constituent.variables, 3, 
1032                                                  &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
1033                }
1034              else
1035                {
1036                  library_fragment.copy (output_file, constituent.variables, 3, 
1037                                         &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
1038                }
1039            }
1040          else
1041            {
1042              application_fragment.copy (output_file, constituent.variables, 4,
1043                                         &CONSTITUENT, &CONSTITUENTSUFFIX, 
1044                                         &OBJS, &LINKMACRO);
1045            }
1046        }
1047    }
1048
1049  LINE = "";
1050  for (i = 0; i < sources.size (); i++)
1051    {
1052      file = sources[i];
1053
1054      set_full_name (full_name, file);
1055      if (full_name == "") continue;
1056
1057      static CmtSystem::cmt_string_vector files;
1058      get_all_files (full_name, files);
1059
1060      int count = 0;
1061
1062      for (int j = 0; j < files.size (); j++)
1063        {
1064          cmt_string& n = files[j];
1065          if (n != "") count++;
1066        }
1067
1068      if (count > 0)
1069        {
1070          LINE += full_name;
1071          LINE += " ";
1072        }
1073    }
1074
1075  filter_paths (LINE.value);
1076
1077  if (constituent.build_triggers)
1078    {
1079      dependencies_and_triggers_fragment.copy (output_file, 
1080                                               constituent.variables, 3,
1081                                               &CONSTITUENT, 
1082                                               &CONSTITUENTSUFFIX, 
1083                                               &LINE);
1084    }
1085  else
1086    {
1087      dependencies_fragment.copy (output_file, 
1088                                  constituent.variables, 3,
1089                                  &CONSTITUENT, 
1090                                  &CONSTITUENTSUFFIX, 
1091                                  &LINE);
1092    }
1093
1094  //----------------------------------------------------
1095  //
1096  // Building actual individual targets.
1097  //
1098  //----------------------------------------------------
1099
1100  for (i = 0; i < source_files.size (); i++)
1101    {
1102      SourceFile& file = source_files[i];
1103      Language& language = file.language ();
1104
1105      if (language == "java")
1106        {
1107          java_file_action (file, constituent);
1108        }
1109      else
1110        {
1111          module_file_action (file, constituent);
1112        }
1113    }
1114
1115  if (PACKOS9)
1116    {
1117      if (os9sources != "")
1118        {
1119          //
1120          // Generate transfers to the OS9 area.
1121          //
1122
1123          ALLOS9SOURCES = "";
1124          allsources = "";
1125        }
1126    }
1127
1128  /*
1129    for file in `cmt_sort_line.csh ${os9sources}` ; do
1130    if test `echo ${file} | grep '$(src)'` ; then
1131    name=`echo ${file} | sed 's#$(src)##'`
1132    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
1133    allsources="${allsources} ${file}"
1134    elif test `echo ${file} | grep '$(inc)'` ; then
1135    name=`echo ${file} | sed 's#$(inc)##'`
1136    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
1137    allsources="${allsources} ${file}"
1138    fi
1139    done
1140
1141    if test ! "${ALLOS9SOURCES}" = "" ; then
1142
1143    sed -e "`subs_vars ALLOS9SOURCES`" \
1144    ${os9_header_fragment} \
1145    >>${output}
1146
1147    for FULLNAME in ${allsources} ; do
1148
1149    NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'`
1150
1151    sed -e "`subs_vars NAME FULLNAME`" \
1152    ${os9_fragment} \
1153    >>${output}
1154
1155    done
1156    fi
1157    fi
1158    fi
1159  */
1160
1161  //
1162  //  Generate package cleanup operations.
1163  //
1164
1165  cleanup_header_fragment.copy (output_file, constituent.variables, 2, 
1166                                &CONSTITUENT, &CONSTITUENTSUFFIX);
1167
1168  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
1169  if (need_prototypes)
1170    {
1171      if (protos != "")
1172        {
1173          FULLNAME = protos;
1174          cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME);
1175          FULLNAME = PROTOSTAMPS;
1176          cleanup_fragment.copy (output_file, constituent.variables, 1, &FULLNAME);
1177        }
1178    }
1179
1180  if (LINKMACRO == "java")
1181    {
1182      cleanup_java_fragment.copy (output_file, constituent.variables, 1, &OBJS);
1183
1184      if (!is_library)
1185        {
1186          if (constituent.need_check)
1187            {
1188              check_java_fragment.copy (output_file, constituent.variables, 2, 
1189                                        &CONSTITUENT, &CONSTITUENTSUFFIX);
1190            }
1191        }
1192    }
1193  else
1194    {
1195      if (is_library)
1196        {
1197          cleanup_library_fragment.copy (output_file, constituent.variables, 2, 
1198                                         &CONSTITUENT, &CONSTITUENTSUFFIX);
1199        }
1200      else
1201        {
1202          cleanup_application_fragment.copy (output_file, constituent.variables, 2, 
1203                                             &CONSTITUENT, &CONSTITUENTSUFFIX);
1204          if (OBJS != "")
1205            {
1206              cleanup_objects_fragment.copy (output_file, constituent.variables, 3, 
1207                                             &OBJS, &CONSTITUENT, &CONSTITUENTSUFFIX);
1208            }
1209
1210          if (constituent.need_check)
1211            {
1212              check_application_fragment.copy (output_file, constituent.variables, 2, 
1213                                               &CONSTITUENT, &CONSTITUENTSUFFIX);
1214            }
1215        }
1216    }
1217}
1218
1219//--------------------------------------------------
1220void MakefileGenerator::build_document_makefile (const cmt_string& package,
1221                                                 const Constituent& constituent)
1222{
1223  static cmt_string names;
1224  static cmt_string output_dir;
1225  static cmt_string name;
1226  static cmt_string full_name;
1227  static cmt_string suffix;
1228  static cmt_string output_suffix;
1229  static cmt_string fragment_suffix;
1230  int i;
1231
1232  cout << TITLE << " " << CONSTITUENT << endl;
1233
1234  //
1235  // Prepare the include paths.
1236  //
1237
1238  const CmtSystem::cmt_string_vector& includes = constituent.includes;
1239
1240  for (i = 0; i < includes.size (); i++)
1241    {
1242      const cmt_string& subdir = includes[i];
1243
1244      PACKINCLUDES += " -I";
1245      PACKINCLUDES += subdir;
1246    }
1247
1248  //
1249  // Get the fragment associated with the document style
1250  //
1251
1252  FragmentHandle fragment (GENERATOR);
1253
1254  fragment_suffix = fragment.suffix ();
1255
1256  output_suffix = ".";
1257
1258  if (fragment_suffix == "")
1259    {
1260      output_suffix += fragment.name ();
1261    }
1262  else
1263    {
1264      output_suffix += fragment_suffix;
1265    }
1266
1267  //
1268  // Scan the sources.
1269  //
1270
1271  const CmtSystem::cmt_string_vector& sources = constituent.modules;
1272
1273  for (i = 0; i < sources.size (); i++)
1274    {
1275      cmt_string& file = sources[i];
1276
1277      set_full_name (full_name, file);
1278      if (full_name == "") continue;
1279
1280      static CmtSystem::cmt_string_vector files;
1281
1282      get_all_files (full_name, files);
1283
1284      for (int j = 0; j < files.size (); j++)
1285        {
1286          const cmt_string& name = files[j];
1287
1288          if (name != "") 
1289            {
1290              analyze_document_file (name, constituent.name, output_suffix);
1291            }
1292        }
1293    }
1294
1295  fill_outputs ();
1296
1297  prepare_use_context ();
1298
1299  DATE = CmtSystem::now ();
1300  USER = CmtSystem::user ();
1301  PACKAGE = package;
1302
1303  make_header_fragment.copy (output_file, constituent.variables, 6,
1304                             &TITLE, &CONSTITUENT, &CONSTITUENTSUFFIX,
1305                             &USER, &DATE, &PACKAGE);
1306
1307  const cmt_string& header = fragment.header ();
1308
1309  //
1310  // If the document type specifies a header, use it .
1311  // otherwise, use the default document header fragment.
1312  //
1313  if (header != "")
1314    {
1315      FragmentHandle header_fragment (header);
1316      header_fragment.copy (output_file, constituent.variables, 3, 
1317                            &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
1318    }
1319  else
1320    {
1321      document_header_fragment.copy (output_file, constituent.variables, 3, 
1322                                     &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
1323    }
1324
1325  if (fragment.need_dependencies ())
1326    {
1327      LINE = "";
1328      for (i = 0; i < sources.size (); i++)
1329        {
1330          cmt_string& file = sources[i];
1331
1332          set_full_name (full_name, file);
1333          if (full_name == "") continue;
1334
1335          static CmtSystem::cmt_string_vector files;
1336          get_all_files (full_name, files);
1337
1338          int count = 0;
1339
1340          for (int j = 0; j < files.size (); j++)
1341            {
1342              cmt_string& n = files[j];
1343              if (n != "") count++;
1344            }
1345
1346          if (count > 0)
1347            {
1348              LINE += full_name;
1349              LINE += " ";
1350            }
1351        }
1352
1353      filter_paths (LINE.value);
1354
1355      dependencies_fragment.copy (output_file, constituent.variables, 3, 
1356                                  &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE);
1357    }
1358  else
1359    {
1360      for (i = 0; i < sources.size (); i++)
1361        {
1362          cmt_string& file = sources[i];
1363         
1364          set_full_name (full_name, file);
1365          if (full_name == "") continue;
1366         
1367          static CmtSystem::cmt_string_vector files;
1368         
1369          get_all_files (full_name, files);
1370         
1371          for (int j = 0; j < files.size (); j++)
1372            {
1373              const cmt_string& name = files[j];
1374             
1375              if (name != "") 
1376                {
1377                  static cmt_string s;
1378                  static cmt_string n;
1379                 
1380                  CmtSystem::get_dot_suffix (name, s);
1381                  CmtSystem::basename (name, s, n);
1382                  CmtSystem::get_suffix (name, s);
1383                 
1384                  fprintf (output_file, "%s_%s_dependencies = %s\n",
1385                           n.c_str (),
1386                           s.c_str (),
1387                           name.c_str ());
1388                }
1389            }
1390        }
1391    }
1392 
1393  SUFFIX = fragment_suffix;
1394  for (i = 0; i < source_files.size (); i++)
1395    {
1396      SourceFile& file = source_files[i];
1397      const cmt_string& file_name = file.name ();
1398      FULLNAME = file_name;
1399      CmtSystem::get_dot_suffix (file_name, suffix);
1400      CmtSystem::basename (file_name, suffix, NAME.value);
1401      CmtSystem::dirname (file_name, FILEPATH.value);
1402      if (FILEPATH.value != "") FILEPATH.value += CmtSystem::file_separator ();
1403      filter_paths (FILEPATH.value);
1404      CmtSystem::basename (file_name, FILENAME.value);
1405      CmtSystem::get_dot_suffix (FILENAME.value, FILESUFFIX.value);
1406
1407      if (!CmtSystem::test_file (file_name))
1408        {
1409          cout << "#CMT> Warning : Source file " << file_name << " not found" << endl;
1410        }
1411
1412      filter_paths (FULLNAME.value);
1413
1414      fragment.copy (output_file, constituent.variables, 8,
1415                     &FILEPATH, &SUFFIX,
1416                     &CONSTITUENT, &CONSTITUENTSUFFIX, &FILENAME,
1417                     &NAME, &FULLNAME, &FILESUFFIX);
1418    }
1419
1420  const cmt_string& trailer = fragment.trailer ();
1421  if (trailer != "")
1422    {
1423      FragmentHandle trailer_fragment (trailer);
1424      trailer_fragment.copy (output_file, constituent.variables, 3, 
1425                             &CONSTITUENT, &CONSTITUENTSUFFIX, &OBJS);
1426    }
1427
1428  //
1429  //  Generate package cleanup operations.
1430  //
1431
1432  cleanup_header_fragment.copy (output_file, constituent.variables, 2, 
1433                                &CONSTITUENT, &CONSTITUENTSUFFIX);
1434}
1435
1436//--------------------------------------------------
1437void MakefileGenerator::prepare_use_context ()
1438{
1439  cmt_string path;
1440  cmt_string substitution;
1441
1442  Use* use = &Use::current ();
1443
1444  deps_builder.clear ();
1445
1446  if (use->include_path != "none")
1447    {
1448      if (use->include_path == "")
1449        {
1450          deps_builder.add (incdir, "$(src)");
1451        }
1452      else
1453        {
1454          substitution = use->include_path;
1455         
1456          path = substitution;
1457          Symbol::expand (path);
1458         
1459          if (CmtSystem::file_separator () == '/')
1460            {
1461              path.replace_all ("\\", "/");
1462              path.replace_all ("//", "/");
1463            }
1464          else
1465            {
1466              path.replace_all ("/", "\\");
1467              path.replace_all ("\\\\", "\\");
1468            }
1469        }
1470     
1471      deps_builder.add (path, substitution);
1472    }
1473
1474  deps_builder.add_includes (*use);
1475
1476  Use::UsePtrVector& uses = Use::uses ();
1477
1478  if (uses.size () > 0)
1479    {
1480      int number;
1481
1482      for (number = 0; number < uses.size (); number++)
1483        {
1484          use = uses[number];
1485          if (use->discarded) continue;
1486
1487          if (use->real_path != "")
1488            {
1489              if (use->include_path != "none")
1490                {
1491                  if (use->include_path == "")
1492                    {
1493                      path = use->real_path;
1494                      path += CmtSystem::file_separator ();
1495                      path += use->package;
1496                      path += CmtSystem::file_separator ();
1497                      path += use->version;
1498                      path += CmtSystem::file_separator ();
1499                      path += "src";
1500
1501                      substitution = "$(";
1502                      substitution += use->prefix;
1503                      substitution += "ROOT)";
1504                      substitution += CmtSystem::file_separator ();
1505                      substitution += "src";
1506                      substitution += CmtSystem::file_separator ();
1507                    }
1508                  else
1509                    {
1510                      substitution = use->include_path;
1511
1512                      path = substitution;
1513                      Symbol::expand (path);
1514
1515                      if (CmtSystem::file_separator () == '/')
1516                        {
1517                          path.replace_all ("\\", "/");
1518                          path.replace_all ("//", "/");
1519                        }
1520                      else
1521                        {
1522                          path.replace_all ("/", "\\");
1523                          path.replace_all ("\\\\", "\\");
1524                        }
1525                    }
1526
1527                  deps_builder.add (path, substitution);
1528                }
1529
1530              deps_builder.add_includes (*use);
1531            }
1532        }
1533    }
1534}
1535
1536//--------------------------------------------------
1537void MakefileGenerator::set_full_name (cmt_string& full_name, cmt_string& file)
1538{
1539  full_name = "";
1540
1541  Symbol::expand (file);
1542
1543  if (file == "") return;
1544 
1545  if (!CmtSystem::absolute_path (file))
1546    {
1547      full_name = srcdir;
1548      if (full_name != "") full_name += CmtSystem::file_separator ();
1549    }
1550 
1551  full_name += file;
1552
1553  char sep = CmtSystem::file_separator ();
1554  if (sep == '/') 
1555    {
1556      full_name.replace_all ("\\", sep);
1557      full_name.replace_all ("//", "/");
1558    }
1559  else
1560    {
1561      full_name.replace_all ("/", sep);
1562      full_name.replace_all ("\\\\", "\\");
1563    }
1564}
1565
1566//--------------------------------------------------
1567void Generator::commit (const cmt_string& name)
1568{
1569  static cmt_string old;
1570  static cmt_string backup;
1571
1572  old = name;
1573
1574  int pos = old.find_last_of ("new");
1575  old.erase (pos);
1576
1577  if (CmtSystem::test_file (old))
1578    {
1579      backup = old;
1580      backup += "sav";
1581
1582      unlink (backup.c_str ());
1583      rename (old.c_str (), backup.c_str ());
1584    }
1585
1586  rename (name.c_str (), old.c_str ());
1587}
1588
1589//--------------------------------------------------
1590void Generator::check (const cmt_string& name)
1591{
1592  static cmt_string old;
1593  static cmt_string backup;
1594
1595  old = name;
1596
1597  int pos = old.find_last_of ("new");
1598  old.erase (pos);
1599
1600  if (!CmtSystem::compare_files (old, name))
1601    {
1602      backup = old;
1603      backup += "sav";
1604
1605      unlink (backup.c_str ());
1606      rename (old.c_str (), backup.c_str ());
1607      rename (name.c_str (), old.c_str ());
1608    }
1609  else
1610    {
1611      unlink (name);
1612    }
1613}
1614
1615//--------------------------------------------------
1616int Generator::build_msdev_workspace (const Constituent::ConstituentVector& constituents)
1617{
1618  Context.reset ();
1619
1620  const cmt_string& package = Cmt::get_current_package ();
1621
1622  cmt_string output = Context.msdevdir + package + ".dswnew";
1623
1624  Context.output_file = fopen (output.c_str (), "wb");
1625  if (Context.output_file != NULL)
1626    {
1627      PACKAGE = package;
1628      dsw_header_fragment.wincopy (Context.output_file, 1, &PACKAGE);
1629
1630      int i;
1631
1632      dsw_all_project_header_fragment.wincopy (Context.output_file,
1633                                               1, &PACKAGE);
1634
1635      for (i = 0; i < constituents.size (); i++)
1636        {
1637          const Constituent& constituent = constituents[i];
1638
1639          if (constituent.type == Library)
1640            {
1641              CONSTITUENT = constituent.name;
1642              CONSTITUENTSUFFIX = constituent.suffix;
1643              dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3,
1644                                                           &PACKAGE,
1645                                                           &CONSTITUENT, 
1646                                                           &CONSTITUENTSUFFIX);
1647            }
1648          else
1649            {
1650              CONSTITUENT = constituent.name;
1651              CONSTITUENTSUFFIX = constituent.suffix;
1652              dsw_all_project_dependency_fragment.wincopy (Context.output_file, constituent.variables, 3,
1653                                                           &PACKAGE,
1654                                                           &CONSTITUENT, 
1655                                                           &CONSTITUENTSUFFIX);
1656            }
1657
1658        }
1659
1660      dsw_all_project_trailer_fragment.wincopy (Context.output_file,
1661                                                1, &PACKAGE);
1662
1663      for (i = 0; i < constituents.size (); i++)
1664        {
1665          const Constituent& constituent = constituents[i];
1666
1667          if (constituent.type == Library)
1668            {
1669              CONSTITUENT = constituent.name;
1670              CONSTITUENTSUFFIX = constituent.suffix;
1671              dsw_project_fragment.wincopy (Context.output_file,
1672                                            constituent.variables, 3,
1673                                            &PACKAGE,
1674                                            &CONSTITUENT, 
1675                                            &CONSTITUENTSUFFIX);
1676            }
1677          else
1678            {
1679              CONSTITUENT = constituent.name;
1680              CONSTITUENTSUFFIX = constituent.suffix;
1681              dsw_project_fragment.wincopy (Context.output_file, constituent.variables, 3, 
1682                                            &PACKAGE,
1683                                            &CONSTITUENT, 
1684                                            &CONSTITUENTSUFFIX);
1685            }
1686        }
1687
1688      dsw_trailer_fragment.wincopy (Context.output_file, 1, &PACKAGE);
1689
1690      fclose (Context.output_file);
1691
1692      //--- Complete the operation --------------
1693
1694      commit (output);
1695    }
1696
1697  output = Context.msdevdir + "all.dspnew";
1698
1699  Context.output_file = fopen (output.c_str (), "wb");
1700  if (Context.output_file != NULL)
1701    {
1702      dsp_all_fragment.wincopy (Context.output_file, 1, &PACKAGE);
1703      fclose (Context.output_file);
1704
1705      //--- Complete the operation --------------
1706
1707      commit (output);
1708    }
1709
1710  return (0);
1711}
1712
1713//--------------------------------------------------
1714int Generator::build_msdev (const Constituent& constituent)
1715{
1716  Context.reset ();
1717
1718  const cmt_string& package = Cmt::get_current_package ();
1719  static cmt_string file;
1720  static cmt_string full_name;
1721  static cmt_string suffix;
1722
1723  int i;
1724
1725  CONSTITUENT = constituent.name;
1726  CONSTITUENTSUFFIX = constituent.suffix;
1727
1728  for (i = 0; i < constituent.includes.size (); i++)
1729    {
1730      const cmt_string& include = constituent.includes[i];
1731      Context.PACKINCLUDES += " -I" + include;
1732    }
1733
1734  switch (constituent.type)
1735    {
1736    case Application:
1737      Context.is_application = true;
1738      TITLE = "Application";
1739      break;
1740    case Library:
1741      Context.is_library = true;
1742      TITLE = "Library";
1743      break;
1744    case Document:
1745      Context.is_document = true;
1746      Context.GENERATOR = constituent.generator;
1747      TITLE = "Document";
1748      break;
1749    }
1750
1751  Context.PACKOS9 = constituent.need_OS9;
1752
1753  const CmtSystem::cmt_string_vector& sources = constituent.modules;
1754
1755  //--- Build the constituents fragment -----
1756  cmt_string output;
1757  cmt_string output_s;
1758
1759  FILE* output_file = NULL;
1760  FILE* output_file_s = NULL;
1761
1762  output = Context.msdevdir + CONSTITUENT + ".dspnew";
1763  output_file = fopen (output.c_str (), "wb");
1764
1765  if ((output_file == NULL) && (output_file_s == NULL)) return (0);
1766
1767  PACKAGE = package;
1768
1769  if (Context.is_library)
1770    {
1771      if (constituent.no_share)
1772        {
1773          LIBRARYSUFFIX = "lib";
1774        }
1775      else
1776        {
1777          LIBRARYSUFFIX = "arc";
1778        }
1779
1780      dsp_library_header_fragment.wincopy (output_file, constituent.variables, 4,
1781                                           &PACKAGE,
1782                                           &CONSTITUENT, 
1783                                           &CONSTITUENTSUFFIX, 
1784                                           &LIBRARYSUFFIX);
1785    }
1786  else
1787    {
1788      if (constituent.windows)
1789        {
1790          dsp_windows_header_fragment.wincopy (output_file, constituent.variables, 3,
1791                                               &PACKAGE,
1792                                               &CONSTITUENT, 
1793                                               &CONSTITUENTSUFFIX);
1794        }
1795      else
1796        {
1797          dsp_application_header_fragment.wincopy (output_file, constituent.variables, 3,
1798                                                   &PACKAGE,
1799                                                   &CONSTITUENT, 
1800                                                   &CONSTITUENTSUFFIX);
1801        }
1802    }
1803
1804  for (i = 0; i < sources.size (); i++)
1805    {
1806      file = sources[i];
1807
1808      Context.set_full_name (full_name, file);
1809      if (full_name == "") continue;
1810
1811      static CmtSystem::cmt_string_vector files;
1812
1813      get_all_files (full_name, files);
1814
1815      for (int j = 0; j < files.size (); j++)
1816        {
1817          const cmt_string& name = files[j];
1818
1819          if (name != "") 
1820            {
1821              FULLNAME = name;
1822
1823              if (output_file != NULL)
1824                {
1825                  dsp_contents_fragment.wincopy (output_file, constituent.variables, 2, 
1826                                                 &PACKAGE, 
1827                                                 &FULLNAME);
1828                }
1829              if (output_file_s != NULL)
1830                {
1831                  dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 2, 
1832                                                 &PACKAGE,
1833                                                 &FULLNAME);
1834                }
1835            }
1836        }
1837
1838      /*
1839        CmtSystem::get_suffix (full_name, suffix);
1840
1841        if (file.find ('*') != cmt_string::npos)
1842        {
1843        static CmtSystem::cmt_string_vector files;
1844
1845        CmtSystem::scan_dir (full_name, files);
1846
1847        if (Cmt::get_debug ())
1848        {
1849        cout << "CMT> full_name=" << full_name <<
1850        " pwd=" << CmtSystem::pwd () << endl;
1851        cout << "CMT> files.size=" <<  files.size () << endl;
1852        }
1853
1854        for (int j = 0; j < files.size (); j++)
1855        {
1856        const cmt_string& nnn = files[j];
1857        static cmt_string sss;
1858
1859        CmtSystem::get_suffix (nnn, sss);
1860        if (sss == suffix)
1861        {
1862        FULLNAME = nnn;
1863        if (output_file != NULL)
1864        {
1865        dsp_contents_fragment.wincopy (output_file,
1866        constituent.variables, 1, &FULLNAME);
1867        }
1868        if (output_file_s != NULL)
1869        {
1870        dsp_contents_fragment.wincopy (output_file_s,
1871        constituent.variables, 1, &FULLNAME);
1872        }
1873        }
1874        }
1875        }
1876        else
1877        {
1878        FULLNAME = full_name;
1879        if (output_file != NULL)
1880        {
1881        dsp_contents_fragment.wincopy (output_file, constituent.variables, 1, &FULLNAME);
1882        }
1883        if (output_file_s != NULL)
1884        {
1885        dsp_contents_fragment.wincopy (output_file_s, constituent.variables, 1, &FULLNAME);
1886        }
1887        }
1888      */
1889    }
1890
1891  if (output_file != NULL)
1892    {
1893      dsp_trailer_fragment.wincopy (output_file, constituent.variables, 3,
1894                                    &PACKAGE,
1895                                    &CONSTITUENT, 
1896                                    &CONSTITUENTSUFFIX);
1897      fclose (output_file);
1898      commit (output);
1899    }
1900
1901  if (output_file_s != NULL)
1902    {
1903      dsp_trailer_fragment.wincopy (output_file_s, constituent.variables, 3,
1904                                    &PACKAGE,
1905                                    &CONSTITUENT, 
1906                                    &CONSTITUENTSUFFIX);
1907      fclose (output_file_s);
1908      commit (output_s);
1909    }
1910
1911  return (0);
1912}
1913
1914//--------------------------------------------------
1915void Generator::build_make_setup (const cmt_string& package)
1916{
1917  Context.reset ();
1918
1919  PACKAGE = package;
1920
1921  FILE* output_file;
1922
1923  cmt_string file_name = "setup.";
1924
1925  if (Cmt::build_nmake ())
1926    {
1927      file_name += "nmake";
1928    }
1929  else
1930    {
1931      file_name += "make";
1932    }
1933 
1934  cmt_string new_file_name = file_name;
1935  new_file_name += "new";
1936
1937  output_file = fopen (new_file_name, "wb");
1938
1939  if (output_file != NULL)
1940    {
1941      int number;
1942      const Use::UsePtrVector& uses = Use::uses ();
1943      const Constituent::ConstituentVector& constituents =
1944        Constituent::constituents ();
1945      cmt_string temp;
1946
1947      make_setup_header_fragment.copy (output_file, 1, &PACKAGE);
1948
1949      for (number = 0; number < uses.size (); number++)
1950        {
1951          const Use* use = uses[number];
1952
1953          if (use->discarded) continue;
1954
1955          if (use->real_path != "")
1956            {
1957              temp  = use->prefix;
1958              temp += "ROOT = ";
1959              temp += use->real_path;
1960              temp += SLASH;
1961              temp += use->package;
1962              temp += SLASH;
1963              temp += use->version;
1964
1965              fprintf (output_file, "%s\n", temp.c_str());
1966            }
1967        }
1968
1969      temp  = "use_requirements = ";
1970      temp += "requirements ";
1971
1972      for (number = 0; number < uses.size (); number++)
1973        {
1974          const Use* use = uses[number];
1975
1976          if (use->discarded) continue;
1977
1978          if (use->real_path != "")
1979            {
1980              temp += "$(";
1981              temp += use->prefix;
1982              temp += "ROOT)";
1983              temp += CmtSystem::file_separator ();
1984              switch (use->style)
1985                {
1986                case cmt_style:
1987                  temp += "cmt";
1988                  break;
1989                case mgr_style:
1990                  temp += "mgr";
1991                  break;
1992                }
1993              temp += CmtSystem::file_separator ();
1994              temp += "requirements ";
1995            }
1996        }
1997
1998      fprintf (output_file, "%s\n", temp.c_str());
1999
2000      temp  = "constituents = $(constituents)";
2001      Symbol::expand (temp);
2002
2003      fprintf (output_file, "%s\n", temp.c_str());
2004
2005      make_setup_fragment.copy (output_file, 1, &PACKAGE);
2006
2007      fclose (output_file);
2008
2009      //--- Complete the operation --------------
2010
2011      commit (new_file_name);
2012    }
2013
2014  /*
2015    for option in $*
2016    do
2017    case ${option} in
2018    args-tag=*)
2019    tag=${option}
2020    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2021    ;;
2022    -tag=*)
2023    tag=args${option}
2024    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2025    ;;
2026    esac
2027    done
2028
2029    if test "${tag}" = "" ; then
2030    tag=${CMTCONFIG}
2031    fi
2032
2033    build_shell_setup_files ${tag}
2034
2035    now=`date`
2036
2037  */
2038}
2039
2040//--------------------------------------------------
2041void Generator::build_constituents_makefile (const cmt_string& package)
2042{
2043  Context.reset ();
2044  cmt_string file_name = "constituents.";
2045
2046  //--- Build the constituents fragment -----
2047
2048  if (Cmt::build_nmake ())
2049    {
2050      file_name += "nmake";
2051    }
2052  else
2053    {
2054      file_name += "make";
2055    }
2056
2057  cmt_string save_file_name = file_name;
2058  save_file_name += "sav";
2059
2060  if (CmtSystem::test_file (file_name))
2061    {
2062      rename (file_name, save_file_name);
2063    }
2064
2065  cmt_string new_file_name = file_name;
2066  new_file_name += "new";
2067
2068  FILE* output_file = fopen (new_file_name, "wb");
2069  if (output_file != NULL)
2070    {
2071      int number;
2072      const Constituent::ConstituentVector&
2073        constituents = Constituent::constituents ();
2074
2075      PACKAGE = package;
2076
2077      constituents_header_fragment.copy (output_file, 1, &PACKAGE);
2078
2079      GROUP = "all";
2080      group_fragment.copy (output_file, 1, &GROUP);
2081
2082      const Group::GroupVector& groups = Group::groups ();
2083
2084      for (number = 0; number < groups.size (); number++)
2085        {
2086          const Group& group = groups[number];
2087
2088          GROUP = group.name ();
2089
2090          group_fragment.copy (output_file, 1, &GROUP);
2091        }
2092     
2093      for (number = 0; number < constituents.size (); number++)
2094        {
2095          const Constituent& constituent = constituents[number];
2096
2097          CONSTITUENT = constituent.name;
2098          CONSTITUENTSUFFIX = constituent.suffix;
2099
2100          LINE = "";
2101
2102          const CmtSystem::cmt_string_vector& sources = constituent.modules;
2103
2104          constituent_fragment.copy (output_file, constituent.variables, 3, 
2105                                     &CONSTITUENT, &CONSTITUENTSUFFIX, &LINE);
2106
2107          if (constituent.need_check)
2108            {
2109              check_application_header_fragment.copy (output_file, 
2110                                                      constituent.variables, 2,
2111                                                      &CONSTITUENT, &CONSTITUENTSUFFIX);
2112            }
2113        }
2114
2115      constituents_trailer_fragment.copy (output_file, 0);
2116
2117      fclose (output_file);
2118
2119      commit (new_file_name);
2120    }
2121}
2122
2123//--------------------------------------------------
2124int Generator::build_constituent_makefile (const Constituent& constituent)
2125{
2126  Context.reset ();
2127
2128  const cmt_string& package = Cmt::get_current_package ();
2129
2130  int i;
2131
2132  PACKAGE = package;
2133  CONSTITUENT = constituent.name;
2134  CONSTITUENTSUFFIX = constituent.suffix;
2135
2136  for (i = 0; i < constituent.includes.size (); i++)
2137    {
2138      const cmt_string& include = constituent.includes[i];
2139      Context.PACKINCLUDES += " -I" + include;
2140    }
2141
2142  switch (constituent.type)
2143    {
2144    case Application:
2145      Context.is_library = false;
2146      Context.is_application = true;
2147      Context.is_document = false;
2148      TITLE = "Application";
2149      break;
2150    case Library:
2151      Context.is_library = true;
2152      Context.is_application = false;
2153      Context.is_document = false;
2154      TITLE = "Library";
2155      break;
2156    case Document:
2157      Context.is_library = false;
2158      Context.is_application = false;
2159      Context.is_document = true;
2160      Context.GENERATOR = constituent.generator;
2161      TITLE = "Document";
2162      break;
2163    }
2164
2165  Context.PACKOS9 = constituent.need_OS9;
2166
2167  cmt_string output = Context.cmtdir + CONSTITUENT + ".";
2168
2169  if (Cmt::build_nmake ())
2170    {
2171      output += "nmake";
2172    }
2173  else
2174    {
2175      output += "make";
2176    }
2177 
2178  output += "new";
2179
2180
2181  Context.output_file = fopen (output.c_str (), "wb");
2182  if (Context.output_file != NULL)
2183    {
2184      if (Context.is_library)
2185        {
2186          Context.build_library_makefile (package, constituent);
2187        }
2188      else if (Context.is_application)
2189        {
2190          Context.build_application_makefile (package, constituent);
2191        }
2192      else if (Context.is_document)
2193        {
2194          Context.build_document_makefile (package, constituent);
2195        }
2196
2197      fclose (Context.output_file);
2198
2199      //--- Complete the operation --------------
2200
2201      commit (output);
2202    }
2203
2204  return (0);
2205}
2206
2207//--------------------------------------------------
2208void Generator::build_constituent_makefile (const cmt_string& name)
2209{
2210  const Constituent* constituent = Constituent::find (name);
2211  if (constituent != 0) build_constituent_makefile (*constituent);
2212}
2213
2214//--------------------------------------------------
2215void Generator::build_default_makefile ()
2216{
2217  cmt_string makefile;
2218
2219  //--- Build a simple Makefile if none is installed
2220
2221#ifndef WIN32
2222
2223  bool need_makefile = false;
2224
2225  makefile = Context.cmtdir + "Makefile";
2226
2227  if (!CmtSystem::test_file (makefile))
2228    {
2229      need_makefile = true;
2230    }
2231  else
2232    {
2233      static cmt_string s;
2234
2235      s.read (makefile);
2236      if ((s.find ("METHODSROOT") != cmt_string::npos) ||
2237          (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos))
2238        {
2239          static cmt_string backup = makefile;
2240          backup += "_backup";
2241
2242          makefile += ".cmt";
2243
2244          if (!CmtSystem::test_file (makefile))
2245            {
2246              FILE* file = fopen (backup.c_str (), "wb");
2247              if (file != NULL)
2248                {
2249                  cout << "# " << endl;
2250                  cout << "#CMT> Warning !!! " << endl;
2251                  cout << "# A Makefile already exists "
2252                    "but it does not provides " << endl;
2253                  cout << "# the recommended features "
2254                    "for a full benefit of CMT" << endl;
2255                  cout << "# " << endl;
2256                  cout << "# CMT is now building "
2257                    "a new 'Makefile.cmt' which you can use" << endl;
2258                  cout << "# to upgrade your current one." << endl;
2259                  cout << "# " << endl;
2260
2261                  s.write (file);
2262                  fclose (file);
2263
2264                  need_makefile = true;
2265                }
2266            }
2267        }
2268    }
2269
2270  if (need_makefile)
2271    {
2272      FILE* file = fopen (makefile.c_str (), "wb");
2273      if (file != NULL)
2274        {
2275          fprintf (file, "include $(CMTROOT)/src/Makefile.header\n");
2276          fprintf (file, "\n");
2277          fprintf (file, "include $(CMTROOT)/src/constituents.make\n");
2278          fprintf (file, "\n");
2279          fclose (file);
2280        }
2281    }
2282
2283#endif
2284
2285#ifdef WIN32
2286
2287  makefile = Context.cmtdir + "NMake";
2288
2289  if (!CmtSystem::test_file (makefile))
2290    {
2291      FILE* file = fopen (makefile.c_str (), "wb");
2292      if (file != NULL)
2293        {
2294          fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n");
2295          fprintf (file, "\n");
2296          fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n");
2297          fprintf (file, "\n");
2298          fclose (file);
2299        }
2300    }
2301
2302#endif
2303
2304}
2305
2306//--------------------------------------------------
2307cmt_string Generator::build_dependencies (const cmt_string& file_name)
2308{
2309  static cmt_string full_name;
2310  static cmt_string suffix;
2311  static cmt_string name;
2312  static cmt_string line;
2313
2314  full_name = "";
2315  line = "";
2316
2317  if (!CmtSystem::absolute_path (file_name))
2318    {
2319      full_name = Context.srcdir;
2320    }
2321
2322  full_name += file_name;
2323
2324  CmtSystem::get_dot_suffix (full_name, suffix);
2325  CmtSystem::basename (full_name, suffix, name);
2326  CmtSystem::get_suffix (full_name, suffix);
2327
2328  if (name == "requirements") return (line);
2329
2330  const CmtSystem::cmt_string_vector& deps = Context.deps_builder.run (full_name);
2331
2332  line  = name;
2333  line += "_";
2334  line += suffix;
2335  line += "_dependencies = ";
2336  line += full_name;
2337  line += " ";
2338
2339  for (int j = 0; j < deps.size (); j++)
2340    {
2341      line += deps[j];
2342      line += " ";
2343    }
2344
2345  filter_paths (line);
2346
2347  return (line);
2348}
2349
2350//--------------------------------------------------
2351//  o text contains lines with a pattern like :
2352//      key = xxxxx
2353//
2354//  o line follows the same pattern
2355//
2356//   This function appends <line> to <text> only if the key found in
2357//  <line> is not found in <text>
2358//--------------------------------------------------
2359static void add_line_to_text (const cmt_string& line, cmt_string& text)
2360{
2361  static const cmt_string empty;
2362
2363  int pos = line.find (" = ");
2364  if (pos != cmt_string::npos)
2365    {
2366      static cmt_string key;
2367      line.substr (0, pos + 3, key);
2368      pos = text.find (key);
2369      if (pos != cmt_string::npos)
2370        {
2371          // The key in line exists in text.
2372          // Now check if the key is exactly the same.
2373
2374          if ((pos == 0) || (text[pos -1] == '\n'))
2375            {
2376              // The key is either in the first line or
2377              // exactly matches '^key = ...'
2378
2379              int nl = text.find (pos, "\n");
2380              if (nl != cmt_string::npos)
2381                {
2382                  static cmt_string old;
2383                  text.substr (pos, nl - pos + 1, old);
2384                  text.replace (old, empty);
2385                }
2386              else
2387                {
2388                  text.erase (pos);
2389                }
2390            }
2391        }
2392    }
2393  if (line != "")
2394    {
2395      text += line;
2396      text += "\n";
2397    }
2398}
2399
2400//--------------------------------------------------
2401class DependencyFilter : public Awk
2402{
2403public:
2404  DependencyFilter ()
2405      {
2406      }
2407
2408  void begin ()
2409      {
2410        m_sources = "";
2411      }
2412
2413  void filter (const cmt_string& line)
2414      {
2415        int pos = line.find ("_dependencies = ");
2416        if (pos == cmt_string::npos) return;
2417
2418        cmt_string s = line;
2419        s.erase (pos);
2420
2421        m_sources += " ";
2422        m_sources += s;
2423        m_sources += " ";
2424
2425          //pos = s.find_last_of ("_");
2426          //if (pos != cmt_string::npos) s[pos] = "."
2427      }
2428
2429  void add_source (const cmt_string& file_name)
2430      {
2431        static cmt_string suffix;
2432        static cmt_string name;
2433
2434        CmtSystem::get_dot_suffix (file_name, suffix);
2435        CmtSystem::basename (file_name, suffix, name);
2436        CmtSystem::get_suffix (file_name, suffix);
2437
2438        cmt_string s = " ";
2439        s += name;
2440        s += "_";
2441        s += suffix;
2442        s += " ";
2443
2444        if (m_sources.find (s) == cmt_string::npos)
2445          {
2446            m_sources += s;
2447          }       
2448      }
2449
2450  bool has_source (const cmt_string& file_name) const
2451      {
2452        static cmt_string suffix;
2453        static cmt_string name;
2454
2455        CmtSystem::get_dot_suffix (file_name, suffix);
2456        CmtSystem::basename (file_name, suffix, name);
2457        CmtSystem::get_suffix (file_name, suffix);
2458
2459        cmt_string s = " ";
2460        s += name;
2461        s += "_";
2462        s += suffix;
2463        s += " ";
2464
2465        if (m_sources.find (s) == cmt_string::npos)
2466          {
2467            return (false);
2468          }
2469        else
2470          {
2471            return (true);
2472          }
2473      }
2474
2475  cmt_string& get_sources ()
2476      {
2477        return (m_sources);
2478      }
2479
2480private:
2481  cmt_string m_sources;
2482};
2483
2484//--------------------------------------------------
2485void Generator::build_dependencies (const cmt_string& name,
2486                                    int argc, char* argv[])
2487{
2488  Context.reset ();
2489  Context.prepare_use_context ();
2490
2491  const Constituent* constituent_ptr = Constituent::find (name);
2492  if (constituent_ptr == 0)
2493    {
2494      // Error : wrong constituent name...
2495      return;
2496    }
2497
2498  const Constituent& constituent = *constituent_ptr;
2499
2500  cmt_string file_name;
2501  cmt_string full_name;
2502  cmt_string compressed_name;
2503  cmt_string suffix;
2504  cmt_string dependencies;
2505
2506  static cmt_string output_name;
2507
2508  cmt_string branch = CmtSystem::current_branch ();
2509
2510  if ((branch == "mgr") || (branch == "cmt"))
2511    {
2512      Use& current_use = Use::current ();
2513
2514      if (current_use.package == "CMT")
2515        {
2516          output_name = "../";
2517          output_name += CmtSystem::getenv ("CMTBIN");
2518          output_name += CmtSystem::file_separator ();
2519        }
2520      else
2521        {
2522          output_name = "${bin}";
2523        }
2524
2525      Symbol::expand (output_name);
2526
2527      //cerr << "output_name=" << output_name << endl;
2528      //cerr << "current_tag=" << Cmt::current_tag << endl;
2529    }
2530
2531  output_name += name;
2532  output_name += "_";
2533  output_name += "dependencies.";
2534  if (Cmt::build_nmake ())
2535    {
2536      output_name += "nmake";
2537    }
2538  else
2539    {
2540      output_name += "make";
2541    }
2542
2543  static DependencyFilter filter;
2544
2545  dependencies.read (output_name);
2546
2547  filter.run (dependencies);
2548
2549  //
2550  // Scan the sources.
2551  //
2552
2553    //
2554    //  We have to rebuild the dependencies for :
2555    //
2556    //   o all sources if the parameter -all_sources has been received
2557    //   o otherwise,
2558    //      + all source names provided in the argument list (if any)
2559    //      + all source names missing from the existing dependency file (if any)
2560    //
2561
2562  const CmtSystem::cmt_string_vector& sources = constituent.modules;
2563  bool all_sources = false;
2564
2565  int source_number = argc;
2566  int i;
2567
2568  for (i = argc-1; i >= 0; i--)
2569    {
2570      file_name = argv[i];
2571
2572        // Get rid of files that may come from the makefile fragment
2573      if (file_name.find ("requirements") != cmt_string::npos) source_number--;
2574      else if (file_name.find (".make") != cmt_string::npos) source_number--;
2575      else if (file_name == "-all_sources") 
2576        {
2577          source_number = sources.size ();
2578          all_sources = true;
2579        }
2580    }
2581
2582
2583  if (all_sources)
2584    {
2585      for (i = 0; i < sources.size (); i++)
2586        {
2587          file_name = sources[i];
2588         
2589          Context.set_full_name (full_name, file_name);
2590          if (full_name == "") continue;
2591
2592          CmtSystem::compress_path (full_name, compressed_name);
2593          full_name = compressed_name;
2594         
2595          static CmtSystem::cmt_string_vector files;
2596
2597          get_all_files (full_name, files);
2598
2599          for (int j = 0; j < files.size (); j++)
2600            {
2601              const cmt_string& name = files[j];
2602             
2603              if (name != "") 
2604                {
2605                  const cmt_string& line = build_dependencies (name);
2606                 
2607                    //cout << ">>> name1=" << name << endl;
2608                 
2609                  add_line_to_text (line, dependencies);
2610                }
2611            }
2612        }
2613    }
2614  else
2615    {
2616      for (i = 0; i < source_number; i++)
2617        {
2618          file_name = argv[i];
2619         
2620          Context.set_full_name (full_name, file_name);
2621          if (full_name == "") continue;
2622
2623          CmtSystem::compress_path (full_name, compressed_name);
2624          full_name = compressed_name;
2625         
2626          const cmt_string& line = build_dependencies (full_name);
2627                 
2628            //cout << ">>> name2=" << full_name << endl;
2629                 
2630          add_line_to_text (line, dependencies);
2631
2632            //cout << ">>from deps : " << filter.get_sources () << endl;
2633          filter.add_source (full_name);
2634
2635        }
2636
2637        //cout << ">>from deps : " << filter.get_sources () << endl;
2638
2639        // Now : are there still any missing source file in dependencies??
2640
2641      for (i = 0; i < sources.size (); i++)
2642        {
2643          file_name = sources[i];
2644         
2645          Context.set_full_name (full_name, file_name);
2646          if (full_name == "") continue;
2647         
2648          CmtSystem::compress_path (full_name, compressed_name);
2649          full_name = compressed_name;
2650         
2651          static CmtSystem::cmt_string_vector files;
2652         
2653          get_all_files (full_name, files);
2654
2655          for (int j = 0; j < files.size (); j++)
2656            {
2657              const cmt_string& name = files[j];
2658             
2659              if (name != "") 
2660                {
2661                  if (!filter.has_source (name))
2662                    {
2663                      const cmt_string& line = build_dependencies (name);
2664                 
2665                        //cout << ">>> name3=" << name << endl;
2666                 
2667                      add_line_to_text (line, dependencies);
2668                    }
2669                }
2670            }
2671        }
2672    }
2673
2674  FILE* f = fopen (output_name.c_str (), "wb");
2675
2676  if (f == 0)
2677    {
2678      cerr << "Cannot open " << output_name << " for write" << endl;
2679    }
2680  else
2681    {
2682      dependencies.write (f);
2683      fclose (f);
2684    }
2685}
2686
2687//--------------------------------------------------
2688class Prototyper : public FAwk
2689{
2690public:
2691  Prototyper (bool static_functions = false) :
2692    m_static_functions(static_functions)
2693  {
2694    if (m_static_functions)
2695      {
2696        m_suffix = "_static.phnew";
2697        m_define_suffix = "_static_ph";
2698      }
2699    else
2700      {
2701        m_suffix = ".phnew";
2702        m_define_suffix = "_ph";
2703      }
2704  }
2705
2706  void begin ()
2707  {
2708    m_running = false;
2709
2710    static cmt_string suffix;
2711    static cmt_string name;
2712
2713    CmtSystem::get_dot_suffix (m_file_name, suffix);
2714    CmtSystem::basename (m_file_name, suffix, name);
2715
2716    m_out_file_name  = "";
2717
2718    if (m_dir_name != "")
2719      {
2720        m_out_file_name  = m_dir_name;
2721        m_out_file_name += CmtSystem::file_separator ();
2722      }
2723
2724    m_out_file_name += name;
2725    m_out_file_name += m_suffix;
2726
2727    CmtSystem::basename (m_file_name, suffix, m_file_name);
2728
2729    m_output = fopen (m_out_file_name.c_str (), "wb");
2730
2731    if (m_output != 0)
2732      {
2733        fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (),
2734                 m_define_suffix.c_str ());
2735        fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (),
2736                 m_define_suffix.c_str ());
2737
2738        fprintf (m_output, "\n");
2739        fprintf (m_output, "#ifdef __cplusplus\n");
2740        fprintf (m_output, "extern \"C\" {\n");
2741        fprintf (m_output, "#endif\n");
2742        fprintf (m_output, "\n");
2743      }
2744    else
2745      {
2746        stop ();
2747      }
2748  }
2749
2750  void filter (const cmt_string& line)
2751  {
2752    char c = line[0];
2753
2754    if (!m_running)
2755      {
2756        if ((c == ' ') ||
2757            (c == '/') ||
2758            (c == '|') ||
2759            (c == '\t') ||
2760            (c == '#')) return;
2761        if (line.find ('(') == cmt_string::npos)
2762          {
2763            m_prev_line = line;
2764            return;
2765          }
2766
2767        m_running = true;
2768        m_full_line = line;
2769        m_full_line.replace ("(", " (");
2770
2771        static CmtSystem::cmt_string_vector words;
2772
2773        CmtSystem::split (m_full_line, " \t", words);
2774
2775        const cmt_string& second = words[1];
2776        if (second[0] == '(')
2777          {
2778            m_full_line = m_prev_line;
2779            m_full_line += " ";
2780            m_full_line += line;
2781
2782            m_prev_line = "";
2783          }
2784      }
2785    else
2786      {
2787        m_full_line += line;
2788      }
2789    if (line.find (')') == cmt_string::npos) return;
2790    m_running = false;
2791
2792    if (m_full_line.find (';') != cmt_string::npos) return;
2793    if (m_full_line.find ("::") != cmt_string::npos) return;
2794    if (m_full_line.find ('<') != cmt_string::npos) return;
2795    if (m_full_line.find ('>') != cmt_string::npos) return;
2796    if (m_full_line.find ('{') != cmt_string::npos) return;
2797    if (m_full_line.find ('}') != cmt_string::npos) return;
2798    if (m_full_line.find ("typedef") != cmt_string::npos) return;
2799    if (m_full_line.find ("yy") != cmt_string::npos) return;
2800    if (m_full_line.find ("YY") != cmt_string::npos) return;
2801    if (m_static_functions)
2802      {
2803        if (m_full_line.find ("static") == cmt_string::npos) return;
2804      }
2805    else
2806      {
2807        if (m_full_line.find ("static") != cmt_string::npos) return;
2808      }
2809
2810    m_full_line += ";";
2811
2812    if (m_output != 0)
2813      {
2814        fprintf (m_output, "%s\n", m_full_line.c_str ());
2815      }
2816  }
2817
2818  void end ()
2819  {
2820    if (m_output != 0)
2821      {
2822        fprintf (m_output, "\n");
2823        fprintf (m_output, "#ifdef __cplusplus\n");
2824        fprintf (m_output, "}\n");
2825        fprintf (m_output, "#endif\n");
2826        fprintf (m_output, "\n");
2827        fprintf (m_output, "#endif\n");
2828        fprintf (m_output, "\n");
2829
2830        fclose (m_output);
2831      }
2832
2833    Generator::check (m_out_file_name);
2834  }
2835
2836private:
2837  bool m_running;
2838  cmt_string m_out_file_name;
2839  FILE* m_output;
2840  bool m_static_functions;
2841  cmt_string m_full_line;
2842  cmt_string m_prev_line;
2843  cmt_string m_suffix;
2844  cmt_string m_define_suffix;
2845};
2846//--------------------------------------------------
2847
2848//--------------------------------------------------
2849void Generator::build_prototype (const cmt_string& file_name)
2850{
2851  Prototyper prototyper;
2852
2853  prototyper.run (file_name);
2854  /*
2855    static cmt_string pp;
2856    pp  = incdir;
2857    pp += name;
2858    pp += ".pp";
2859  */
2860}
2861
2862//--------------------------------------------------
2863void Generator::build_readme (const CmtSystem::cmt_string_vector& arguments)
2864{
2865  Context.reset ();
2866
2867  PACKAGE = Cmt::get_current_package ();
2868  VERSION = Cmt::get_current_version ();
2869  DATE = CmtSystem::now ();
2870  USER = CmtSystem::user ();
2871
2872  cmt_string url;
2873  cmt_string doc;
2874
2875  for (int i = 0; i < arguments.size (); i++)
2876    {
2877      cmt_string arg = arguments[i];
2878
2879      if (arg.substr (0, 5) == "-url=")
2880        {
2881          arg.substr (5, url);
2882        }
2883      else if (arg.substr (0, 5) == "-doc=")
2884        {
2885          arg.substr (5, doc);
2886        }
2887    }
2888
2889  cmt_string output = Context.cmtdir + "README.html";
2890
2891  Context.output_file = fopen (output.c_str (), "wb");
2892  if (Context.output_file != NULL)
2893    {
2894      readme_header_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION);
2895
2896      if (doc != "")
2897        {
2898          DOCPATH = doc;
2899          readme_doc_fragment.copy (Context.output_file, 3, &PACKAGE, &VERSION, &DOCPATH);
2900        }
2901
2902      readme_fragment.copy (Context.output_file, 2, &PACKAGE, &VERSION);
2903
2904      int number;
2905      const Use::UsePtrVector& uses = Use::uses ();
2906
2907      for (number = 0; number < uses.size (); number++)
2908        {
2909          const Use* use = uses[number];
2910          if (use->discarded) continue;
2911          if ((use != 0) && (use->package != "CMT"))
2912            {
2913              cmt_string selected_path;
2914
2915              if (url == "")
2916                {
2917                  selected_path = use->real_path;
2918
2919                  if (use->specified_path != "")
2920                    {
2921                      int pos = selected_path.find_last_of (use->specified_path);
2922                      if (pos != cmt_string::npos)
2923                        {
2924                          selected_path.erase (pos);
2925                        }
2926                    }
2927                }
2928              else
2929                {
2930                  selected_path = url;
2931
2932                  if (use->specified_path != "")
2933                    {
2934                      selected_path += CmtSystem::file_separator ();
2935                    }
2936                }
2937
2938              PACKAGEPATH = selected_path;
2939              PACKAGEPREFIX = use->specified_path;
2940              PACKAGE = use->package;
2941              VERSION = use->version;
2942              MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt";
2943              readme_use_fragment.copy (Context.output_file, 5,
2944                                        &PACKAGEPATH,
2945                                        &PACKAGEPREFIX,
2946                                        &PACKAGE,
2947                                        &VERSION,
2948                                        &MGRSTYLE);
2949            }
2950        }
2951      PACKAGE = Cmt::get_current_package ();
2952      VERSION = Cmt::get_current_version ();
2953      readme_trailer_fragment.copy (Context.output_file, 4, 
2954                                    &PACKAGE, 
2955                                    &VERSION, 
2956                                    &DATE, 
2957                                    &USER);
2958    }
2959}
2960
2961class WinDefAwk : public PAwk
2962{
2963public :
2964   WinDefAwk (const cmt_string& library_name)
2965    {
2966      m_name = library_name;
2967    }
2968
2969  void begin ()
2970    {
2971      cout << "LIBRARY " << m_name << endl;
2972      cout << "EXPORTS" << endl;
2973    }
2974
2975  void filter (const cmt_string& line)
2976    {
2977      if (line.find ("External") == cmt_string::npos) return;
2978      if (line.find ("??_") != cmt_string::npos) return;
2979
2980      CmtSystem::cmt_string_vector words;
2981      CmtSystem::split (line, " \t", words);
2982      if (words.size () >= 8)
2983        {
2984          int pos = 7;
2985
2986          cmt_string& fifth_word = words[4];
2987          if (fifth_word == "()") pos = 7;
2988          else if (fifth_word == "External") pos = 6;
2989          else return;
2990
2991          cmt_string& symbol = words[pos];
2992          if (symbol[0] == '_') symbol.erase (0, 1);
2993          symbol.replace_all ("\r", "");
2994          symbol.replace_all ("\n", "");
2995          cout << " " << symbol << (pos == 6 ? "\tDATA" : " ") << endl;
2996        }
2997    }
2998
2999  void end ()
3000    {
3001    }
3002
3003private:
3004  cmt_string m_name;
3005};
3006
3007//--------------------------------------------------
3008void Generator::build_windefs (const cmt_string& library_name)
3009{
3010        cmt_string bin;
3011        cmt_string name;
3012        cmt_string suffix;
3013
3014        CmtSystem::dirname (library_name, bin);
3015        CmtSystem::get_dot_suffix (library_name, suffix);
3016        CmtSystem::basename (library_name, suffix, name);
3017
3018        if (!CmtSystem::cd (bin)) return;
3019       
3020        cmt_string text;
3021        cmt_string command;
3022       
3023        command = "dumpbin /symbols ";
3024        command += library_name;
3025       
3026        WinDefAwk filter (name);
3027       
3028        filter.run (command, "SECT");
3029}
3030
3031//--------------------------------------------------
3032void Packager::begin ()
3033{
3034  m_package_name = "";
3035}
3036
3037void Packager::filter (const cmt_string& line)
3038{
3039  CmtSystem::cmt_string_vector words;
3040
3041  CmtSystem::split (line, " ", words);
3042  if (words.size () > 1)
3043    {
3044      cmt_string& w = words[0];
3045
3046      if (w == "package")
3047        {
3048          m_package_name = words[1];
3049
3050          int pos = m_package_name.find (";");
3051          if (pos != cmt_string::npos) m_package_name.erase (pos);
3052          m_package_name.replace_all (".", CmtSystem::file_separator ());
3053        }
3054    }
3055}
3056
3057cmt_string& Packager::package_name ()
3058{
3059  return (m_package_name);
3060}
3061
Note: See TracBrowser for help on using the repository browser.