source: CMT/v1r25-branch/source/cmt_fragment.cxx @ 664

Last change on this file since 664 was 664, checked in by rybkin, 10 years ago

merge -r 646:663 HEAD

  • Property svn:eol-style set to native
File size: 29.8 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// Modified by Grigory Rybkin
5// See the complete license in cmt_license.txt "http://www.cecill.info".
6//-----------------------------------------------------------
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12
13#include "cmt_fragment.h"
14#include "cmt_use.h"
15#include "cmt_symbol.h"
16#include "cmt_system.h"
17#include "cmt_database.h"
18#include "cmt_log.h"
19#include "cmt_error.h"
20
21/*----------------------------------------------------------*/
22/*                                                          */
23/*  Operations on Variables                                 */
24/*                                                          */
25/*----------------------------------------------------------*/
26
27//----------------------------------------------------------
28Variable* Variable::find (VariableVector& vector, 
29                          const cmt_string& name)
30{
31  for (int i = 0; i < vector.size (); i++)
32    {
33      Variable& v = vector[i];
34
35      if (v.name == name) return (&v);
36    }
37
38  return (0);
39}
40
41//----------------------------------------------------------
42Variable::Variable ()
43{
44}
45
46//----------------------------------------------------------
47Variable::Variable (const cmt_string& n) : name (n)
48{
49  m_macro_braces = "${";
50  m_macro_braces += name;
51  m_macro_braces += "}";
52
53  m_macro_pars = "$(";
54  m_macro_pars += name;
55  m_macro_pars += ")";
56}
57
58//----------------------------------------------------------
59const cmt_string& Variable::macro_braces () const
60{
61  return (m_macro_braces);
62}
63
64//----------------------------------------------------------
65const cmt_string& Variable::macro_pars () const
66{
67  return (m_macro_pars);
68}
69
70//----------------------------------------------------------
71void Variable::set (const cmt_string& new_name,
72                    const cmt_string& new_value)
73{
74  name = new_name;
75  value = new_value;
76
77  m_macro_braces = "${";
78  m_macro_braces += name;
79  m_macro_braces += "}";
80
81  m_macro_pars = "$(";
82  m_macro_pars += name;
83  m_macro_pars += ")";
84}
85
86//----------------------------------------------------------
87Variable& Variable::operator = (const Variable& other)
88{
89  value = other.value;
90  return (*this);
91}
92
93//----------------------------------------------------------
94Variable& Variable::operator = (const cmt_string& v)
95{
96  value = v;
97  return (*this);
98}
99
100//----------------------------------------------------------
101void Variable::operator += (const cmt_string& v)
102{
103  value += v;
104}
105
106//----------------------------------------------------------
107cmt_string Variable::operator + (const cmt_string& v) const
108{
109  return (value + v);
110}
111
112//----------------------------------------------------------
113Variable::operator const cmt_string& () const
114{
115  return (value);
116}
117
118//----------------------------------------------------------
119bool Variable::operator == (const cmt_string& v) const
120{
121  return ((value == v));
122}
123
124//----------------------------------------------------------
125bool Variable::operator != (const cmt_string& v) const
126{
127  return ((value != v));
128}
129
130/*----------------------------------------------------------*/
131/*                                                          */
132/*  Operations on Fragments                                 */
133/*                                                          */
134/*----------------------------------------------------------*/
135
136/*----------------------------------------------------------*/
137void Fragment::show (const cmt_string& name)
138{
139  Fragment* fragment = Fragment::find (name);
140  if (fragment == 0)
141    {
142      cmt_string t (name);
143      //      t += " is not defined";
144      CmtError::set (CmtError::fragment_not_found, t);
145      //      CmtMessage::info ("Fragment " + name + " not found");
146      //      cerr << "Fragment " << name << " not found" << endl;
147    }
148  else
149    {
150      fragment->print ();
151    }
152}
153
154/*----------------------------------------------------------*/
155void Fragment::show_all ()
156{
157  static FragmentVector& Fragments = fragments ();
158
159  int number;
160
161  for (number = 0; number < Fragments.size (); number++)
162    {
163      Fragment& fragment = Fragments[number];
164
165      fragment.print ();
166    }
167}
168
169class fragment_action_iterator
170{
171public:
172
173  fragment_action_iterator (Use* use) :
174    m_need_dependencies (false),
175    m_state (need_name),
176    m_use (use)
177  {
178  }
179
180  void add_word (const cmt_string& w)
181  {
182    switch (m_state)
183      {
184      case need_name:
185        m_name = w;
186        m_state = need_options;
187        break;
188      case need_options:
189        if (w.find ("-suffix=") != cmt_string::npos)
190          {
191            m_suffix = w;
192            m_suffix.replace ("-suffix=", "");
193          }
194        else if (w.find ("-dependencies") != cmt_string::npos)
195          {
196            m_need_dependencies = true;
197          }
198        else if (w.find ("-header=") != cmt_string::npos)
199          {
200            m_header = w;
201            m_header.replace ("-header=", "");
202
203//          if (Fragment::find (m_header) == 0)
204//            {
205            Fragment::add (m_header, "", "", "", false, m_use, "");
206//            }
207          }
208        else if (w.find ("-trailer=") != cmt_string::npos)
209          {
210            m_trailer = w;
211            m_trailer.replace ("-trailer=", "");
212           
213//          if (Fragment::find (m_trailer) == 0)
214//            {
215            Fragment::add (m_trailer, "", "", "", false, m_use, "");
216//            }
217          }
218        else if (0 == m_use || &Use::current () == m_use)
219          {
220            m_path = w;
221          }
222        break;
223      }
224  }
225
226  void commit ()
227  {
228    Fragment::add (m_name, m_suffix, m_header, m_trailer, m_need_dependencies, m_use, m_path);
229  }
230
231private:
232
233  enum
234    {
235      need_name,
236      need_options
237    } m_state;
238
239  cmt_string m_name;
240  cmt_string m_suffix;
241  cmt_string m_header;
242  cmt_string m_trailer;
243  bool m_need_dependencies;
244  Use* m_use;
245  cmt_string m_path;
246};
247
248
249/*----------------------------------------------------------*/
250void Fragment::action (const CmtSystem::cmt_string_vector& words,
251                       Use* use)
252{
253  if ((Cmt::get_current_access () == UserMode) &&
254      (use->get_current_scope () == ScopePrivate)) return;
255
256  if (words.size () <= 1) return;
257
258  fragment_action_iterator it (use);
259
260  for (int i = 1; i < words.size (); i++)
261    {
262      const cmt_string& w = words[i];
263      cmt_string ew = w;
264
265      Symbol::expand (ew);
266      if (ew != w)
267        {
268          CmtSystem::cmt_string_vector ws;
269
270          CmtSystem::split (ew, " ", ws);
271
272          for (int j = 0; j < ws.size (); ++j)
273            {
274              const cmt_string& ww = ws[j];
275              it.add_word (ww);
276            }
277        }
278      else
279        {
280          it.add_word (ew);
281        }
282    }
283
284  it.commit ();
285}
286
287/*----------------------------------------------------------*/
288Fragment* Fragment::find (const cmt_string& name)
289{
290  static FragmentVector& Fragments = fragments ();
291
292  int fragment_index;
293
294  if (Fragments.size () == 0) return (0);
295
296  for (fragment_index = 0;
297       fragment_index < Fragments.size ();
298       fragment_index++)
299    {
300      Fragment& fragment = Fragments[fragment_index];
301
302      if (fragment.name == name)
303        {
304          return (&fragment);
305        }
306    }
307
308  return (0);
309}
310
311/*----------------------------------------------------------*/
312void Fragment::add (const cmt_string& name,
313                    const cmt_string& suffix,
314                    const cmt_string& header,
315                    const cmt_string& trailer,
316                    bool need_dependencies,
317                    Use* use,
318                    const cmt_string& path)
319//                    Use* use)
320{
321  static FragmentVector& Fragments = fragments ();
322
323  {
324    Fragment* fragment;
325
326    if (name == "") return;
327
328    fragment = find (name);
329    if (fragment != 0)
330      {
331        if (suffix != "")
332          {
333            fragment->suffix = suffix;
334          }
335
336        if (header != "")
337          {
338            fragment->header = header;
339          }
340
341        if (trailer != "")
342          {
343            fragment->trailer = trailer;
344          }
345
346        fragment->need_dependencies = need_dependencies;
347
348        fragment->use = use;
349        if (path != "")
350          {
351            fragment->path = path;
352          }
353        return;
354      }
355  }
356
357  Fragment& fragment = Fragments.add ();
358
359  fragment.name              = name;
360  fragment.suffix            = suffix;
361  fragment.header            = header;
362  fragment.trailer           = trailer;
363  fragment.need_dependencies = need_dependencies;
364  fragment.use               = use;
365  fragment.path              = path;
366}
367
368/*----------------------------------------------------------*/
369void Fragment::clear_all ()
370{
371  static FragmentVector& Fragments = fragments ();
372
373  for (int i = 0; i < Fragments.size (); i++)
374    {
375      Fragment& f = Fragments[i];
376      f.clear ();
377    }
378
379  Fragments.clear ();
380}
381
382/*----------------------------------------------------------*/
383Fragment::FragmentVector& Fragment::fragments ()
384{
385  static Database& db = Database::instance ();
386  static FragmentVector& Fragments = db.fragments ();
387
388  return (Fragments);
389}
390
391/*----------------------------------------------------------*/
392Fragment::Fragment ()
393{
394  use = 0;
395}
396
397/*----------------------------------------------------------*/
398Fragment::Fragment (const cmt_string& fragment_name)
399{
400  name = fragment_name;
401  use = 0;
402  path = "";
403}
404
405/*----------------------------------------------------------*/
406Fragment::~Fragment ()
407{
408  use = 0;
409}
410
411/*----------------------------------------------------------*/
412void Fragment::clear ()
413{
414  name    = "";
415  suffix  = "";
416  header  = "";
417  trailer = "";
418  need_dependencies = false;
419  path = "";
420  use  = 0;
421}
422
423/*----------------------------------------------------------*/
424int Fragment::print (PrintMode mode, ostream& out)
425//int Fragment::print ()
426{
427  int result = 1;
428
429  if (name == "") return (0);
430 
431  if (!locate ()) return 0;
432
433  if (use == 0)
434    {
435      Use& u = Use::current();
436      use = &u;
437    }
438 
439  switch (mode)
440    {
441    case Requirements :
442      out << "make_fragment " << name
443          << (suffix != "" ? " -suffix=" + suffix : "")
444          << (header != "" ? " -header=" + header : "")
445          << (trailer != "" ? " -trailer=" + trailer : "")
446          << (need_dependencies ? " -dependencies" : "")
447        ;
448      break;
449    default:
450      break;
451    }
452
453  cmt_string the_path = path;
454
455  switch (mode)
456    {
457    case Requirements :
458      the_path = " " + the_path;
459      break;
460    default:
461      use->reduce_path (the_path);
462      break;
463    }
464 
465  out << the_path;
466
467  switch (mode)
468    {
469    case Requirements :
470      break;
471    default:
472      if (suffix != "")
473        {
474          out << "->" << suffix;
475        }
476      break;
477    }
478
479  out << endl;
480 
481  return (result);
482}
483
484/*----------------------------------------------------------*/
485bool Fragment::locate ()
486{
487  if (path != "") return (true);
488
489  if (use == 0)
490    {
491      // Assume CMT
492      use = Use::find ("CMT");
493    }
494
495  if (Cmt::get_debug ())
496    {
497      cout << "Fragment::locate> " << name
498           << " in " << use->get_package_name () << endl;
499    }
500  cmt_string root_path;
501
502  // First try <root>/cmt/fragments/<name> for Unix
503  //       or <root>/cmt/fragments/nmake/<name> for Win
504
505  use->get_full_path (root_path);
506
507  if (use->style == cmt_style)
508    {
509      root_path += CmtSystem::file_separator ();
510      root_path += "cmt";
511    }
512  else if (use->style == mgr_style)
513    {
514      root_path += CmtSystem::file_separator ();
515      root_path += "mgr";
516    }
517 
518  root_path += CmtSystem::file_separator ();
519  root_path += "fragments";
520  root_path += CmtSystem::file_separator ();
521 
522  path = root_path;
523 
524  if (Cmt::build_nmake ())
525    {
526      path += "nmake";
527      path += CmtSystem::file_separator ();
528    }
529 
530  path += name;
531  //cerr << "test_file: " << path << endl; 
532  if (CmtSystem::test_file (path)) return (true);
533
534  // Then try <root>/cmt/fragments/<name> for Win
535
536  if (Cmt::build_nmake ())
537    {
538      path = root_path;
539      path += name;
540     
541      if (CmtSystem::test_file (path)) return (true);
542    }
543
544  // Then try <root>/fragments/<name> for Unix
545  //      or <root>/fragments/nmake/<name> for Win
546
547  use->get_full_path (root_path);
548
549  root_path += CmtSystem::file_separator ();
550  root_path += "fragments";
551  root_path += CmtSystem::file_separator ();
552
553  path = root_path;
554 
555  if (Cmt::build_nmake ())
556    {
557      path += "nmake";
558      path += CmtSystem::file_separator ();
559    }
560 
561  path += name;
562
563  //cerr << "test_file: " << path << endl; 
564  if (CmtSystem::test_file (path)) return (true);
565
566  // Then try <root>/fragments/<name> for Win
567
568  if (Cmt::build_nmake ())
569    {
570      path = root_path;
571      path += name;
572
573      if (CmtSystem::test_file (path)) return (true);
574    }
575
576  CmtMessage::warning
577    (CmtError::get_error_name (CmtError::fragment_not_found)
578     + ": " + name + " (declared by " + use->get_package_name () + ")");
579
580  path = "";
581  return (false);
582}
583
584//--------------------------------------------------
585bool Fragment::copy (FILE* out,
586                     const cmt_string& name,
587                     int variables, ...)
588{
589  va_list ids;
590
591  Fragment* fragment = Fragment::find (name);
592  if (fragment == 0) return (false);
593
594  va_start (ids, variables);
595  bool result = fragment->copy (out, variables, ids);
596  va_end (ids);
597
598  return (result);
599}
600
601//--------------------------------------------------
602bool Fragment::copy (cmt_string& out,
603                     const cmt_string& name,
604                     int variables, ...)
605{
606  va_list ids;
607
608  Fragment* fragment = Fragment::find (name);
609  if (fragment == 0) return (false);
610
611  va_start (ids, variables);
612  bool result = fragment->copy (out, variables, ids);
613  va_end (ids);
614
615  return (result);
616}
617
618//--------------------------------------------------
619bool Fragment::copy (FILE* out, int variables, ...)
620{
621  va_list ids;
622
623  va_start (ids, variables);
624  bool result = copy (out, variables, ids);
625  va_end (ids);
626
627  return (result);
628}
629
630//--------------------------------------------------
631bool Fragment::copy (cmt_string& out, int variables, ...)
632{
633  va_list ids;
634
635  va_start (ids, variables);
636  bool result = copy (out, variables, ids);
637  va_end (ids);
638
639  return (result);
640}
641
642//--------------------------------------------------
643bool Fragment::copy (FILE* out, int variables, va_list ids)
644{
645  static cmt_string cline;
646
647  bool result = copy (cline, variables, ids);
648  if (result)
649    {
650      cline.write (out);
651      return (true);
652    }
653  else
654    {
655      return (false);
656    }
657}
658
659//--------------------------------------------------
660bool Fragment::copy (cmt_string& out, int variables, va_list ids)
661{
662  int i;
663
664  if (!locate ()) return (false);
665
666  if (!out.read (path))
667    {
668      CmtError::set (CmtError::file_access_error, path);
669      return false;
670    }
671 
672  Variable* var = 0;
673  for (i = 0; i < variables; i++)
674    {
675      var = va_arg (ids, Variable*);
676      out.replace_all (var->macro_braces (), var->value);
677      out.replace_all (var->macro_pars (), var->value);
678    }
679
680  return (true);
681}
682
683//--------------------------------------------------
684bool Fragment::wincopy (FILE* out, int variables, va_list ids)
685{
686  static cmt_string cline;
687
688  bool result = wincopy (cline, variables, ids);
689
690  if (result)
691    {
692      cline.write (out);
693      return (true);
694    }
695  else
696    {
697      return (false);
698    }
699}
700
701//--------------------------------------------------
702bool Fragment::wincopy (cmt_string& out, int variables, va_list ids)
703{
704  int i;
705
706  if (!locate ()) return (false);
707
708  out.read (path);
709
710  Variable* var = 0;
711  for (i = 0; i < variables; i++)
712    {
713      var = va_arg (ids, Variable*);
714      out.replace_all (var->macro_braces (), var->value);
715      out.replace_all (var->macro_pars (), var->value);
716    }
717
718  cmt_string pattern;
719  cmt_string macro_name;
720  char end_pattern;
721
722  int start = 0;
723
724  for (;;)
725    {
726      //
727      // Try and substitute all ${xxx} or $(xxx) patterns
728      // using symbol values.
729      //
730      int par;
731      int brace;
732      int begin;
733
734      par = out.find (start, "$(");
735      brace = out.find (start, "${");
736
737      if (par == cmt_string::npos)
738        {
739          // No parentheses. Look for brace
740          if (brace == cmt_string::npos)
741            {
742              // No pattern, finish the scan.
743              break;
744            }
745
746          // Brace found
747          end_pattern = '}';
748          begin = brace;
749        }
750      else
751        {
752          // Parenthese found. Look for closest from {par, brace}
753          if ((brace == cmt_string::npos) ||
754              (brace > par))
755            {
756              end_pattern = ')';
757              begin = par;
758            }
759          else
760            {
761              end_pattern = '}';
762              begin = brace;
763            }
764        }
765
766      // Skip the pattern intro.
767      start = begin + 2;
768
769      int end;
770      end = out.find (start, end_pattern);
771      if (end == cmt_string::npos)
772        {
773          // The pattern is a fake one (no ending!)
774          break;
775        }
776
777      // This should never happen...
778      if (end < begin) break;
779
780      // Extract the complete pattern
781      out.substr (begin, end - begin + 1, pattern);
782
783      // Then only the macro name
784      out.substr (begin + 2, end - begin - 2, macro_name);
785
786      if (macro_name == "CFG")
787        {
788          // This is a Windows reserved keyword...
789          start = end + 1;
790        }
791      else
792        {
793          Symbol* macro = Symbol::find (macro_name);
794          if (macro != 0)
795            {
796              // Macro found
797              cmt_string value = macro->resolve_macro_value ();
798
799              out.replace_all (pattern, value);
800
801              // The substitution will restart from the same place
802              // allowing for recursive replacements
803              start = begin;
804            }
805          else
806            {
807              // Macro not found. Look for env. variable
808              cmt_string value = CmtSystem::getenv (macro_name);
809
810              out.replace_all (pattern, value);
811
812              // The substitution will restart from the same place
813              // allowing for recursive replacements
814              start = begin;
815            }
816        }
817    }
818
819  // Uniformly install CR-LF doublets.
820
821  out.replace_all ("\r\n", "\n");
822  out.replace_all ("\n", "\r\n");
823
824  return (true);
825}
826
827
828
829
830
831
832
833
834//--------------------------------------------------
835bool Fragment::copy (FILE* out,
836                     const cmt_string& name,
837                     const Variable::VariableVector& vector, 
838                     int variables, ...)
839{
840  va_list ids;
841
842  Fragment* fragment = Fragment::find (name);
843  if (fragment == 0) return (false);
844
845  va_start (ids, variables);
846  bool result = fragment->copy (out, vector, variables, ids);
847  va_end (ids);
848
849  return (result);
850}
851
852//--------------------------------------------------
853bool Fragment::copy (cmt_string& out,
854                     const cmt_string& name,
855                     const Variable::VariableVector& vector, 
856                     int variables, ...)
857{
858  va_list ids;
859
860  Fragment* fragment = Fragment::find (name);
861  if (fragment == 0) return (false);
862
863  va_start (ids, variables);
864  bool result = fragment->copy (out, vector, variables, ids);
865  va_end (ids);
866
867  return (result);
868}
869
870//--------------------------------------------------
871bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
872{
873  va_list ids;
874
875  va_start (ids, variables);
876  bool result = copy (out, vector, variables, ids);
877  va_end (ids);
878
879  return (result);
880}
881
882//--------------------------------------------------
883bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
884{
885  va_list ids;
886
887  va_start (ids, variables);
888  bool result = copy (out, vector, variables, ids);
889  va_end (ids);
890
891  return (result);
892}
893
894//--------------------------------------------------
895bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
896{
897  static cmt_string cline;
898
899  bool result = copy (cline, vector, variables, ids);
900  if (result)
901    {
902      cline.write (out);
903      return (true);
904    }
905  else
906    {
907      return (false);
908    }
909}
910
911//--------------------------------------------------
912bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, va_list ids)
913{
914  int i;
915
916  if (!locate ()) return (false);
917
918  out.read (path);
919
920  Variable* var = 0;
921
922  for (i = 0; i < vector.size (); i++)
923    {
924      var = &(vector[i]);
925      out.replace_all (var->macro_braces (), var->value);
926      out.replace_all (var->macro_pars (), var->value);
927    }
928
929  for (i = 0; i < variables; i++)
930    {
931      var = va_arg (ids, Variable*);
932      out.replace_all (var->macro_braces (), var->value);
933      out.replace_all (var->macro_pars (), var->value);
934    }
935
936  return (true);
937}
938
939//--------------------------------------------------
940bool Fragment::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
941{
942  static cmt_string cline;
943
944  bool result = wincopy (cline, vector, variables, ids);
945  if (result)
946    {
947      cline.write (out);
948      return (true);
949    }
950  else
951    {
952      return (false);
953    }
954}
955
956//--------------------------------------------------
957bool Fragment::wincopy (cmt_string& out, const Variable::VariableVector& vector, 
958                        int variables, va_list ids)
959{
960  int i;
961
962  if (!locate ()) return (false);
963
964  out.read (path);
965
966  Variable* var = 0;
967
968  for (i = 0; i < vector.size (); i++)
969    {
970      var = &(vector[i]);
971      out.replace_all (var->macro_braces (), var->value);
972      out.replace_all (var->macro_pars (), var->value);
973    }
974
975  for (i = 0; i < variables; i++)
976    {
977      var = va_arg (ids, Variable*);
978      out.replace_all (var->macro_braces (), var->value);
979      out.replace_all (var->macro_pars (), var->value);
980    }
981
982  cmt_string pattern;
983  cmt_string macro_name;
984  char end_pattern;
985
986  int start = 0;
987
988  for (;;)
989    {
990      //
991      // Try and substitute all ${xxx} or $(xxx) patterns
992      // using symbol values.
993      //
994      int par;
995      int brace;
996      int begin;
997
998      par = out.find (start, "$(");
999      brace = out.find (start, "${");
1000
1001      if (par == cmt_string::npos)
1002        {
1003          // No parentheses. Look for brace
1004          if (brace == cmt_string::npos)
1005            {
1006              // No pattern, finish the scan.
1007              break;
1008            }
1009
1010          // Brace found
1011          end_pattern = '}';
1012          begin = brace;
1013        }
1014      else
1015        {
1016          // Parenthese found. Look for closest from {par, brace}
1017          if ((brace == cmt_string::npos) ||
1018              (brace > par))
1019            {
1020              end_pattern = ')';
1021              begin = par;
1022            }
1023          else
1024            {
1025              end_pattern = '}';
1026              begin = brace;
1027            }
1028        }
1029
1030      // Skip the pattern intro.
1031      start = begin + 2;
1032
1033      int end;
1034      end = out.find (start, end_pattern);
1035      if (end == cmt_string::npos)
1036        {
1037          // The pattern is a fake one (no ending!)
1038          break;
1039        }
1040
1041      // This should never happen...
1042      if (end < begin) break;
1043
1044      // Extract the complete pattern
1045      out.substr (begin, end - begin + 1, pattern);
1046
1047      // Then only the macro name
1048      out.substr (begin + 2, end - begin - 2, macro_name);
1049
1050      if (macro_name == "CFG")
1051        {
1052          // This is a Windows reserved keyword...
1053          start = end + 1;
1054        }
1055      else
1056        {
1057          Symbol* macro = Symbol::find (macro_name);
1058          if (macro != 0)
1059            {
1060              // Macro found
1061              cmt_string value = macro->resolve_macro_value ();
1062              out.replace_all (pattern, value);
1063
1064              // The substitution will restart from the same place
1065              // allowing for recursive replacements
1066              start = begin;
1067            }
1068          else
1069            {
1070              // Macro not found. Look for env. variable
1071              cmt_string value = CmtSystem::getenv (macro_name);
1072              out.replace_all (pattern, value);
1073
1074              // The substitution will restart from the same place
1075              // allowing for recursive replacements
1076              start = begin;
1077            }
1078        }
1079    }
1080
1081  // Uniformly install CR-LF doublets.
1082
1083  out.replace_all ("\r\n", "\n");
1084  out.replace_all ("\n", "\r\n");
1085
1086  return (true);
1087}
1088
1089//--------------------------------------------------
1090FragmentHandle::FragmentHandle ()
1091{
1092  _fragment = 0;
1093  _initialized = false;
1094}
1095
1096//--------------------------------------------------
1097FragmentHandle::FragmentHandle (const cmt_string name) : _name(name)
1098{
1099  _fragment = 0;
1100  _initialized = false;
1101}
1102
1103//--------------------------------------------------
1104FragmentHandle& FragmentHandle::operator = (const FragmentHandle& other)
1105{
1106  _name = other._name;
1107  _fragment = 0;
1108  _initialized = false;
1109
1110  return (*this);
1111}
1112
1113//--------------------------------------------------
1114void FragmentHandle::reset ()
1115{
1116  _fragment = 0;
1117  _initialized = false;
1118}
1119
1120//--------------------------------------------------
1121void FragmentHandle::set (const cmt_string name)
1122{
1123  _name = name;
1124  _fragment = 0;
1125  _initialized = false;
1126}
1127
1128//--------------------------------------------------
1129cmt_string& FragmentHandle::name ()
1130{
1131  static cmt_string null_string;
1132
1133  if (!setup ()) return (null_string);
1134
1135  return (_fragment->name);
1136}
1137
1138//--------------------------------------------------
1139cmt_string& FragmentHandle::suffix ()
1140{
1141  static cmt_string null_string;
1142
1143  if (!setup ()) return (null_string);
1144
1145  return (_fragment->suffix);
1146}
1147
1148//--------------------------------------------------
1149cmt_string& FragmentHandle::header ()
1150{
1151  static cmt_string null_string;
1152
1153  if (!setup ()) return (null_string);
1154
1155  return (_fragment->header);
1156}
1157
1158//--------------------------------------------------
1159cmt_string& FragmentHandle::trailer ()
1160{
1161  static cmt_string null_string;
1162
1163  if (!setup ()) return (null_string);
1164
1165  return (_fragment->trailer);
1166}
1167
1168//--------------------------------------------------
1169bool FragmentHandle::need_dependencies ()
1170{
1171  if (!setup ()) return (false);
1172
1173  return (_fragment->need_dependencies);
1174}
1175
1176//--------------------------------------------------
1177bool FragmentHandle::copy (FILE* out, int variables, ...)
1178{
1179  if (!setup ()) return (false);
1180
1181  va_list ids;
1182
1183  va_start (ids, variables);
1184  bool result = _fragment->copy (out, variables, ids);
1185  va_end (ids);
1186
1187  if (!result)
1188    {
1189      //      CmtMessage::info ("Fragment " + _name + " not found");
1190      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1191      _fragment = 0;
1192    }
1193
1194  return (result);
1195}
1196
1197//--------------------------------------------------
1198bool FragmentHandle::copy (cmt_string& out, int variables, ...)
1199{
1200  if (!setup ()) return (false);
1201
1202  va_list ids;
1203
1204  va_start (ids, variables);
1205  bool result = _fragment->copy (out, variables, ids);
1206  va_end (ids);
1207
1208  if (!result)
1209    {
1210      //      CmtMessage::info ("Fragment " + _name + " not found");
1211      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1212      _fragment = 0;
1213    }
1214
1215  return (result);
1216}
1217
1218//--------------------------------------------------
1219bool FragmentHandle::wincopy (FILE* out, int variables, ...)
1220{
1221  if (!setup ()) return (false);
1222
1223  va_list ids;
1224
1225  va_start (ids, variables);
1226  bool result = _fragment->wincopy (out, variables, ids);
1227  va_end (ids);
1228
1229  if (!result)
1230    {
1231      CmtMessage::info ("Fragment " + _name + " not found");
1232      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1233      _fragment = 0;
1234    }
1235
1236  return (result);
1237}
1238
1239//--------------------------------------------------
1240bool FragmentHandle::wincopy (cmt_string& out, int variables, ...)
1241{
1242  if (!setup ()) return (false);
1243
1244  va_list ids;
1245
1246  va_start (ids, variables);
1247  bool result = _fragment->wincopy (out, variables, ids);
1248  va_end (ids);
1249
1250  if (!result)
1251    {
1252      CmtMessage::info ("Fragment " + _name + " not found");
1253      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1254      _fragment = 0;
1255    }
1256
1257  return (result);
1258}
1259
1260
1261
1262
1263//--------------------------------------------------
1264bool FragmentHandle::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
1265{
1266  if (!setup ()) return (false);
1267
1268  va_list ids;
1269
1270  va_start (ids, variables);
1271  bool result = _fragment->copy (out, vector, variables, ids);
1272  va_end (ids);
1273
1274  if (!result)
1275    {
1276      //      CmtMessage::info ("Fragment " + _name + " not found");
1277      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1278      _fragment = 0;
1279    }
1280
1281  return (result);
1282}
1283
1284//--------------------------------------------------
1285bool FragmentHandle::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
1286{
1287  if (!setup ()) return (false);
1288
1289  va_list ids;
1290
1291  va_start (ids, variables);
1292  bool result = _fragment->copy (out, vector, variables, ids);
1293  va_end (ids);
1294
1295  if (!result)
1296    {
1297      //      CmtMessage::info ("Fragment " + _name + " not found");
1298      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1299      _fragment = 0;
1300    }
1301
1302  return (result);
1303}
1304
1305//--------------------------------------------------
1306bool FragmentHandle::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
1307{
1308  if (!setup ()) return (false);
1309
1310  va_list ids;
1311
1312  va_start (ids, variables);
1313  bool result = _fragment->wincopy (out, vector, variables, ids);
1314  va_end (ids);
1315
1316  if (!result)
1317    {
1318      CmtMessage::info ("Fragment " + _name + " not found");
1319      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1320      _fragment = 0;
1321    }
1322
1323  return (result);
1324}
1325
1326//--------------------------------------------------
1327bool FragmentHandle::wincopy (cmt_string& out, 
1328                              const Variable::VariableVector& vector, 
1329                              int variables, ...)
1330{
1331  if (!setup ()) return (false);
1332
1333  va_list ids;
1334
1335  va_start (ids, variables);
1336  bool result = _fragment->wincopy (out, vector, variables, ids);
1337  va_end (ids);
1338
1339  if (!result)
1340    {
1341      CmtMessage::info ("Fragment " + _name + " not found");
1342      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1343      _fragment = 0;
1344    }
1345
1346  return (result);
1347}
1348
1349//--------------------------------------------------
1350bool FragmentHandle::setup ()
1351{
1352  if (!_initialized)
1353    {
1354      _initialized = true;
1355
1356      _fragment = Fragment::find (_name);
1357      if (_fragment == 0)
1358        {
1359          CmtMessage::warning
1360            (CmtError::get_error_name (CmtError::fragment_not_found)
1361             + ": " + _name);
1362          //          cerr << "#CMT> Fragment " << _name << " not found" << endl;
1363        }
1364    }
1365 
1366  if (_fragment == 0)
1367    {
1368      return (false);
1369    }
1370  else
1371    {
1372      return (true);
1373    }
1374}
Note: See TracBrowser for help on using the repository browser.