source: CMT/v1r23/source/cmt_fragment.cxx

Last change on this file was 564, checked in by rybkin, 13 years ago

See C.L. 447

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