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