source: CMT/HEAD/source/cmt_fragment.cxx @ 595

Last change on this file since 595 was 595, checked in by rybkin, 12 years ago

See C.L. 472

  • 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// 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  if (!locate ()) return 0;
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
579  path = "";
580  return (false);
581}
582
583//--------------------------------------------------
584bool Fragment::copy (FILE* out,
585                     const cmt_string& name,
586                     int variables, ...)
587{
588  va_list ids;
589
590  Fragment* fragment = Fragment::find (name);
591  if (fragment == 0) return (false);
592
593  va_start (ids, variables);
594  bool result = fragment->copy (out, variables, ids);
595  va_end (ids);
596
597  return (result);
598}
599
600//--------------------------------------------------
601bool Fragment::copy (cmt_string& out,
602                     const cmt_string& name,
603                     int variables, ...)
604{
605  va_list ids;
606
607  Fragment* fragment = Fragment::find (name);
608  if (fragment == 0) return (false);
609
610  va_start (ids, variables);
611  bool result = fragment->copy (out, variables, ids);
612  va_end (ids);
613
614  return (result);
615}
616
617//--------------------------------------------------
618bool Fragment::copy (FILE* out, int variables, ...)
619{
620  va_list ids;
621
622  va_start (ids, variables);
623  bool result = copy (out, variables, ids);
624  va_end (ids);
625
626  return (result);
627}
628
629//--------------------------------------------------
630bool Fragment::copy (cmt_string& out, int variables, ...)
631{
632  va_list ids;
633
634  va_start (ids, variables);
635  bool result = copy (out, variables, ids);
636  va_end (ids);
637
638  return (result);
639}
640
641//--------------------------------------------------
642bool Fragment::copy (FILE* out, int variables, va_list ids)
643{
644  static cmt_string cline;
645
646  bool result = copy (cline, variables, ids);
647  if (result)
648    {
649      cline.write (out);
650      return (true);
651    }
652  else
653    {
654      return (false);
655    }
656}
657
658//--------------------------------------------------
659bool Fragment::copy (cmt_string& out, int variables, va_list ids)
660{
661  int i;
662
663  if (!locate ()) return (false);
664
665  if (!out.read (path))
666    {
667      CmtError::set (CmtError::file_access_error, path);
668      return false;
669    }
670 
671  Variable* var = 0;
672  for (i = 0; i < variables; i++)
673    {
674      var = va_arg (ids, Variable*);
675      out.replace_all (var->macro_braces (), var->value);
676      out.replace_all (var->macro_pars (), var->value);
677    }
678
679  return (true);
680}
681
682//--------------------------------------------------
683bool Fragment::wincopy (FILE* out, int variables, va_list ids)
684{
685  static cmt_string cline;
686
687  bool result = wincopy (cline, variables, ids);
688
689  if (result)
690    {
691      cline.write (out);
692      return (true);
693    }
694  else
695    {
696      return (false);
697    }
698}
699
700//--------------------------------------------------
701bool Fragment::wincopy (cmt_string& out, int variables, va_list ids)
702{
703  int i;
704
705  if (!locate ()) return (false);
706
707  out.read (path);
708
709  Variable* var = 0;
710  for (i = 0; i < variables; i++)
711    {
712      var = va_arg (ids, Variable*);
713      out.replace_all (var->macro_braces (), var->value);
714      out.replace_all (var->macro_pars (), var->value);
715    }
716
717  cmt_string pattern;
718  cmt_string macro_name;
719  char end_pattern;
720
721  int start = 0;
722
723  for (;;)
724    {
725      //
726      // Try and substitute all ${xxx} or $(xxx) patterns
727      // using symbol values.
728      //
729      int par;
730      int brace;
731      int begin;
732
733      par = out.find (start, "$(");
734      brace = out.find (start, "${");
735
736      if (par == cmt_string::npos)
737        {
738          // No parentheses. Look for brace
739          if (brace == cmt_string::npos)
740            {
741              // No pattern, finish the scan.
742              break;
743            }
744
745          // Brace found
746          end_pattern = '}';
747          begin = brace;
748        }
749      else
750        {
751          // Parenthese found. Look for closest from {par, brace}
752          if ((brace == cmt_string::npos) ||
753              (brace > par))
754            {
755              end_pattern = ')';
756              begin = par;
757            }
758          else
759            {
760              end_pattern = '}';
761              begin = brace;
762            }
763        }
764
765      // Skip the pattern intro.
766      start = begin + 2;
767
768      int end;
769      end = out.find (start, end_pattern);
770      if (end == cmt_string::npos)
771        {
772          // The pattern is a fake one (no ending!)
773          break;
774        }
775
776      // This should never happen...
777      if (end < begin) break;
778
779      // Extract the complete pattern
780      out.substr (begin, end - begin + 1, pattern);
781
782      // Then only the macro name
783      out.substr (begin + 2, end - begin - 2, macro_name);
784
785      if (macro_name == "CFG")
786        {
787          // This is a Windows reserved keyword...
788          start = end + 1;
789        }
790      else
791        {
792          Symbol* macro = Symbol::find (macro_name);
793          if (macro != 0)
794            {
795              // Macro found
796              cmt_string value = macro->resolve_macro_value ();
797
798              out.replace_all (pattern, value);
799
800              // The substitution will restart from the same place
801              // allowing for recursive replacements
802              start = begin;
803            }
804          else
805            {
806              // Macro not found. Look for env. variable
807              cmt_string value = CmtSystem::getenv (macro_name);
808
809              out.replace_all (pattern, value);
810
811              // The substitution will restart from the same place
812              // allowing for recursive replacements
813              start = begin;
814            }
815        }
816    }
817
818  // Uniformly install CR-LF doublets.
819
820  out.replace_all ("\r\n", "\n");
821  out.replace_all ("\n", "\r\n");
822
823  return (true);
824}
825
826
827
828
829
830
831
832
833//--------------------------------------------------
834bool Fragment::copy (FILE* out,
835                     const cmt_string& name,
836                     const Variable::VariableVector& vector, 
837                     int variables, ...)
838{
839  va_list ids;
840
841  Fragment* fragment = Fragment::find (name);
842  if (fragment == 0) return (false);
843
844  va_start (ids, variables);
845  bool result = fragment->copy (out, vector, variables, ids);
846  va_end (ids);
847
848  return (result);
849}
850
851//--------------------------------------------------
852bool Fragment::copy (cmt_string& out,
853                     const cmt_string& name,
854                     const Variable::VariableVector& vector, 
855                     int variables, ...)
856{
857  va_list ids;
858
859  Fragment* fragment = Fragment::find (name);
860  if (fragment == 0) return (false);
861
862  va_start (ids, variables);
863  bool result = fragment->copy (out, vector, variables, ids);
864  va_end (ids);
865
866  return (result);
867}
868
869//--------------------------------------------------
870bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
871{
872  va_list ids;
873
874  va_start (ids, variables);
875  bool result = copy (out, vector, variables, ids);
876  va_end (ids);
877
878  return (result);
879}
880
881//--------------------------------------------------
882bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
883{
884  va_list ids;
885
886  va_start (ids, variables);
887  bool result = copy (out, vector, variables, ids);
888  va_end (ids);
889
890  return (result);
891}
892
893//--------------------------------------------------
894bool Fragment::copy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
895{
896  static cmt_string cline;
897
898  bool result = copy (cline, vector, variables, ids);
899  if (result)
900    {
901      cline.write (out);
902      return (true);
903    }
904  else
905    {
906      return (false);
907    }
908}
909
910//--------------------------------------------------
911bool Fragment::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, va_list ids)
912{
913  int i;
914
915  if (!locate ()) return (false);
916
917  out.read (path);
918
919  Variable* var = 0;
920
921  for (i = 0; i < vector.size (); i++)
922    {
923      var = &(vector[i]);
924      out.replace_all (var->macro_braces (), var->value);
925      out.replace_all (var->macro_pars (), var->value);
926    }
927
928  for (i = 0; i < variables; i++)
929    {
930      var = va_arg (ids, Variable*);
931      out.replace_all (var->macro_braces (), var->value);
932      out.replace_all (var->macro_pars (), var->value);
933    }
934
935  return (true);
936}
937
938//--------------------------------------------------
939bool Fragment::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, va_list ids)
940{
941  static cmt_string cline;
942
943  bool result = wincopy (cline, vector, variables, ids);
944  if (result)
945    {
946      cline.write (out);
947      return (true);
948    }
949  else
950    {
951      return (false);
952    }
953}
954
955//--------------------------------------------------
956bool Fragment::wincopy (cmt_string& out, const Variable::VariableVector& vector, 
957                        int variables, va_list ids)
958{
959  int i;
960
961  if (!locate ()) return (false);
962
963  out.read (path);
964
965  Variable* var = 0;
966
967  for (i = 0; i < vector.size (); i++)
968    {
969      var = &(vector[i]);
970      out.replace_all (var->macro_braces (), var->value);
971      out.replace_all (var->macro_pars (), var->value);
972    }
973
974  for (i = 0; i < variables; i++)
975    {
976      var = va_arg (ids, Variable*);
977      out.replace_all (var->macro_braces (), var->value);
978      out.replace_all (var->macro_pars (), var->value);
979    }
980
981  cmt_string pattern;
982  cmt_string macro_name;
983  char end_pattern;
984
985  int start = 0;
986
987  for (;;)
988    {
989      //
990      // Try and substitute all ${xxx} or $(xxx) patterns
991      // using symbol values.
992      //
993      int par;
994      int brace;
995      int begin;
996
997      par = out.find (start, "$(");
998      brace = out.find (start, "${");
999
1000      if (par == cmt_string::npos)
1001        {
1002          // No parentheses. Look for brace
1003          if (brace == cmt_string::npos)
1004            {
1005              // No pattern, finish the scan.
1006              break;
1007            }
1008
1009          // Brace found
1010          end_pattern = '}';
1011          begin = brace;
1012        }
1013      else
1014        {
1015          // Parenthese found. Look for closest from {par, brace}
1016          if ((brace == cmt_string::npos) ||
1017              (brace > par))
1018            {
1019              end_pattern = ')';
1020              begin = par;
1021            }
1022          else
1023            {
1024              end_pattern = '}';
1025              begin = brace;
1026            }
1027        }
1028
1029      // Skip the pattern intro.
1030      start = begin + 2;
1031
1032      int end;
1033      end = out.find (start, end_pattern);
1034      if (end == cmt_string::npos)
1035        {
1036          // The pattern is a fake one (no ending!)
1037          break;
1038        }
1039
1040      // This should never happen...
1041      if (end < begin) break;
1042
1043      // Extract the complete pattern
1044      out.substr (begin, end - begin + 1, pattern);
1045
1046      // Then only the macro name
1047      out.substr (begin + 2, end - begin - 2, macro_name);
1048
1049      if (macro_name == "CFG")
1050        {
1051          // This is a Windows reserved keyword...
1052          start = end + 1;
1053        }
1054      else
1055        {
1056          Symbol* macro = Symbol::find (macro_name);
1057          if (macro != 0)
1058            {
1059              // Macro found
1060              cmt_string value = macro->resolve_macro_value ();
1061              out.replace_all (pattern, value);
1062
1063              // The substitution will restart from the same place
1064              // allowing for recursive replacements
1065              start = begin;
1066            }
1067          else
1068            {
1069              // Macro not found. Look for env. variable
1070              cmt_string value = CmtSystem::getenv (macro_name);
1071              out.replace_all (pattern, value);
1072
1073              // The substitution will restart from the same place
1074              // allowing for recursive replacements
1075              start = begin;
1076            }
1077        }
1078    }
1079
1080  // Uniformly install CR-LF doublets.
1081
1082  out.replace_all ("\r\n", "\n");
1083  out.replace_all ("\n", "\r\n");
1084
1085  return (true);
1086}
1087
1088//--------------------------------------------------
1089FragmentHandle::FragmentHandle ()
1090{
1091  _fragment = 0;
1092  _initialized = false;
1093}
1094
1095//--------------------------------------------------
1096FragmentHandle::FragmentHandle (const cmt_string name) : _name(name)
1097{
1098  _fragment = 0;
1099  _initialized = false;
1100}
1101
1102//--------------------------------------------------
1103FragmentHandle& FragmentHandle::operator = (const FragmentHandle& other)
1104{
1105  _name = other._name;
1106  _fragment = 0;
1107  _initialized = false;
1108
1109  return (*this);
1110}
1111
1112//--------------------------------------------------
1113void FragmentHandle::reset ()
1114{
1115  _fragment = 0;
1116  _initialized = false;
1117}
1118
1119//--------------------------------------------------
1120void FragmentHandle::set (const cmt_string name)
1121{
1122  _name = name;
1123  _fragment = 0;
1124  _initialized = false;
1125}
1126
1127//--------------------------------------------------
1128cmt_string& FragmentHandle::name ()
1129{
1130  static cmt_string null_string;
1131
1132  if (!setup ()) return (null_string);
1133
1134  return (_fragment->name);
1135}
1136
1137//--------------------------------------------------
1138cmt_string& FragmentHandle::suffix ()
1139{
1140  static cmt_string null_string;
1141
1142  if (!setup ()) return (null_string);
1143
1144  return (_fragment->suffix);
1145}
1146
1147//--------------------------------------------------
1148cmt_string& FragmentHandle::header ()
1149{
1150  static cmt_string null_string;
1151
1152  if (!setup ()) return (null_string);
1153
1154  return (_fragment->header);
1155}
1156
1157//--------------------------------------------------
1158cmt_string& FragmentHandle::trailer ()
1159{
1160  static cmt_string null_string;
1161
1162  if (!setup ()) return (null_string);
1163
1164  return (_fragment->trailer);
1165}
1166
1167//--------------------------------------------------
1168bool FragmentHandle::need_dependencies ()
1169{
1170  if (!setup ()) return (false);
1171
1172  return (_fragment->need_dependencies);
1173}
1174
1175//--------------------------------------------------
1176bool FragmentHandle::copy (FILE* out, int variables, ...)
1177{
1178  if (!setup ()) return (false);
1179
1180  va_list ids;
1181
1182  va_start (ids, variables);
1183  bool result = _fragment->copy (out, variables, ids);
1184  va_end (ids);
1185
1186  if (!result)
1187    {
1188      //      CmtMessage::info ("Fragment " + _name + " not found");
1189      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1190      _fragment = 0;
1191    }
1192
1193  return (result);
1194}
1195
1196//--------------------------------------------------
1197bool FragmentHandle::copy (cmt_string& out, int variables, ...)
1198{
1199  if (!setup ()) return (false);
1200
1201  va_list ids;
1202
1203  va_start (ids, variables);
1204  bool result = _fragment->copy (out, variables, ids);
1205  va_end (ids);
1206
1207  if (!result)
1208    {
1209      //      CmtMessage::info ("Fragment " + _name + " not found");
1210      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1211      _fragment = 0;
1212    }
1213
1214  return (result);
1215}
1216
1217//--------------------------------------------------
1218bool FragmentHandle::wincopy (FILE* out, int variables, ...)
1219{
1220  if (!setup ()) return (false);
1221
1222  va_list ids;
1223
1224  va_start (ids, variables);
1225  bool result = _fragment->wincopy (out, variables, ids);
1226  va_end (ids);
1227
1228  if (!result)
1229    {
1230      CmtMessage::info ("Fragment " + _name + " not found");
1231      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1232      _fragment = 0;
1233    }
1234
1235  return (result);
1236}
1237
1238//--------------------------------------------------
1239bool FragmentHandle::wincopy (cmt_string& out, int variables, ...)
1240{
1241  if (!setup ()) return (false);
1242
1243  va_list ids;
1244
1245  va_start (ids, variables);
1246  bool result = _fragment->wincopy (out, variables, ids);
1247  va_end (ids);
1248
1249  if (!result)
1250    {
1251      CmtMessage::info ("Fragment " + _name + " not found");
1252      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1253      _fragment = 0;
1254    }
1255
1256  return (result);
1257}
1258
1259
1260
1261
1262//--------------------------------------------------
1263bool FragmentHandle::copy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
1264{
1265  if (!setup ()) return (false);
1266
1267  va_list ids;
1268
1269  va_start (ids, variables);
1270  bool result = _fragment->copy (out, vector, variables, ids);
1271  va_end (ids);
1272
1273  if (!result)
1274    {
1275      //      CmtMessage::info ("Fragment " + _name + " not found");
1276      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1277      _fragment = 0;
1278    }
1279
1280  return (result);
1281}
1282
1283//--------------------------------------------------
1284bool FragmentHandle::copy (cmt_string& out, const Variable::VariableVector& vector, int variables, ...)
1285{
1286  if (!setup ()) return (false);
1287
1288  va_list ids;
1289
1290  va_start (ids, variables);
1291  bool result = _fragment->copy (out, vector, variables, ids);
1292  va_end (ids);
1293
1294  if (!result)
1295    {
1296      //      CmtMessage::info ("Fragment " + _name + " not found");
1297      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1298      _fragment = 0;
1299    }
1300
1301  return (result);
1302}
1303
1304//--------------------------------------------------
1305bool FragmentHandle::wincopy (FILE* out, const Variable::VariableVector& vector, int variables, ...)
1306{
1307  if (!setup ()) return (false);
1308
1309  va_list ids;
1310
1311  va_start (ids, variables);
1312  bool result = _fragment->wincopy (out, vector, variables, ids);
1313  va_end (ids);
1314
1315  if (!result)
1316    {
1317      CmtMessage::info ("Fragment " + _name + " not found");
1318      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1319      _fragment = 0;
1320    }
1321
1322  return (result);
1323}
1324
1325//--------------------------------------------------
1326bool FragmentHandle::wincopy (cmt_string& out, 
1327                              const Variable::VariableVector& vector, 
1328                              int variables, ...)
1329{
1330  if (!setup ()) return (false);
1331
1332  va_list ids;
1333
1334  va_start (ids, variables);
1335  bool result = _fragment->wincopy (out, vector, variables, ids);
1336  va_end (ids);
1337
1338  if (!result)
1339    {
1340      CmtMessage::info ("Fragment " + _name + " not found");
1341      //      cerr << "#CMT> Fragment " << _name << " not found" << endl;
1342      _fragment = 0;
1343    }
1344
1345  return (result);
1346}
1347
1348//--------------------------------------------------
1349bool FragmentHandle::setup ()
1350{
1351  if (!_initialized)
1352    {
1353      _initialized = true;
1354
1355      _fragment = Fragment::find (_name);
1356      if (_fragment == 0)
1357        {
1358          CmtMessage::warning
1359            (CmtError::get_error_name (CmtError::fragment_not_found)
1360             + ": " + _name);
1361          //          cerr << "#CMT> Fragment " << _name << " not found" << endl;
1362        }
1363    }
1364 
1365  if (_fragment == 0)
1366    {
1367      return (false);
1368    }
1369  else
1370    {
1371      return (true);
1372    }
1373}
Note: See TracBrowser for help on using the repository browser.