source: CMT/v1r23/source/cmt_deps_builder.cxx

Last change on this file was 427, checked in by rybkin, 17 years ago

See C.L. 333

  • Property svn:eol-style set to native
File size: 25.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 "cmt_deps_builder.h"
8#include "cmt_system.h"
9#include "cmt_use.h"
10#include "cmt_include.h"
11#include "cmt_symbol.h"
12#include "cmt_log.h"
13
14//
15//  While parsing a C++ file, these are the possible usefull
16// states we can reach.
17//  Each state correspond to a specific state action function.
18//
19enum state_def
20  {
21    at_start,                                // beginning of the file
22    in_line,                                // along a line
23    in_string,                        // inside a quoted string
24    in_char,                                // inside a quoted char
25    in_comment,                        // inside a multi-line comment
26    in_string_comment,        // inside a quoted string in a comment
27    in_char_comment,                // inside a quoted char in a comment
28    in_line_comment                // inside a single-line comment
29  };
30
31//--------------------------------------------------
32static int locate (const cmt_string& name,
33                   const cmt_string& dir_name,
34                   const CmtSystem::cmt_string_vector& include_paths,
35                   const CmtSystem::cmt_string_vector& substitutions,
36                   cmt_string& full_name);
37
38//--------------------------------------------------
39static void build_deps_text (char* text,
40                             const cmt_string& dir_name,
41                             int current_path_index,
42                             const CmtSystem::cmt_string_vector& include_paths,
43                             const CmtSystem::cmt_string_vector& substitutions,
44                             const DepsBuilder::HeaderFilters& header_filters,
45                             CmtSystem::cmt_string_vector& all_deps,
46                             CmtSystem::cmt_string_vector& deps);
47
48//--------------------------------------------------
49static void header_file_action (const char* header_file,
50                                const cmt_string& dir_name,
51                                int current_path_index,
52                                const CmtSystem::cmt_string_vector& include_paths,
53                                const CmtSystem::cmt_string_vector& substitutions,
54                                const DepsBuilder::HeaderFilters& header_filters,
55                                CmtSystem::cmt_string_vector& all_deps,
56                                CmtSystem::cmt_string_vector& deps)
57{
58  Log;
59
60  for (int i = 0; i < all_deps.size (); i++)
61    {
62      const cmt_string& n = all_deps[i];
63
64      log << "CMT> check old header file name=" << n << " against " << header_file << log_endl;
65
66      if (n == header_file) return;
67    }
68
69  all_deps.push_back (header_file);
70
71  cmt_string header_file_path;
72  int path_index = locate (header_file,
73                           dir_name,
74                           include_paths,
75                           substitutions,
76                           header_file_path);
77
78  if (path_index < 0) return;
79
80  static int header_filters_size = header_filters.size ();
81  if (header_filters_size > 0)
82    {
83      // check the filter macros from
84      // find all macros named <package>_header_file_filter
85      // for all those macros, get the regexp and check the matches against the header file name
86      // if any match, select the stamp file instead of the header file
87      // the stamp file might be either a conventional name
88      //         <package>/cmt/cmt_all_headers.stamp
89      // or given in a macro eg <package>_header_stamp_file_name
90      //
91      for (int i = header_filters_size - 1; i >= 0; i--)
92        {
93          cmt_string stamp_file;
94          if (header_filters[i].use_stamp (header_file_path, stamp_file))
95            {
96              bool included = false;
97              for (int i = deps.size () - 1; i >= 0; i--)
98                {
99                  if (deps[i] == stamp_file)
100                    {
101                      included = true;
102                      break;
103                    }
104                }
105              if (!included) deps.push_back (stamp_file);
106              return;
107            }
108        }
109    }
110
111  log << "CMT> parsing new header file name=" << header_file << log_endl;
112
113///////////////////////////////////////////////////////////////////////////////////////////////////////
114  cmt_string text;
115  text.read (header_file_path);
116  char* ptr = &text[0];
117  cmt_string new_dir;
118  CmtSystem::dirname (header_file_path, new_dir);
119
120  if (path_index == 0 || path_index == 1)
121    build_deps_text (ptr, new_dir,
122                     current_path_index,
123                     include_paths, substitutions,
124                     header_filters,
125                     all_deps, deps);
126  else
127    build_deps_text (ptr, new_dir,
128                     path_index,
129                     include_paths, substitutions,
130                     header_filters,
131                     all_deps, deps);
132///////////////////////////////////////////////////////////////////////////////////////////////////////
133     
134//path_index >= 0
135
136  cmt_string full_name;
137
138  if (path_index == 1)
139    {
140      full_name = dir_name;
141      full_name += CmtSystem::file_separator ();
142
143      if (current_path_index >= 2)
144        {
145          full_name.replace (include_paths[current_path_index - 2],
146                             substitutions[current_path_index - 2]);
147        }
148    }
149  else if (path_index > 1)
150    {
151      full_name  = substitutions[path_index - 2];
152      full_name += CmtSystem::file_separator ();
153    }
154
155  full_name += header_file;
156
157  deps.push_back (full_name);
158}
159
160
161//--------------------------------------------------
162static char* at_start_action (char* ptr,
163                              state_def& state,
164                              const cmt_string& dir_name,
165                              int current_path_index,
166                              const CmtSystem::cmt_string_vector& include_paths,
167                              const CmtSystem::cmt_string_vector& substitutions,
168                              const DepsBuilder::HeaderFilters& header_filters,
169                              CmtSystem::cmt_string_vector& all_deps,
170                              CmtSystem::cmt_string_vector& deps)
171{
172
173  char term = 0;
174  // To ignore leading spaces and tabs
175  while ( (*ptr == ' ') || (*ptr == '\t'))
176    {
177      ptr++;
178    }
179
180  if (*ptr == '#')
181    {
182      ptr++;
183
184      // skip spaces
185      while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
186
187      if (!strncmp (ptr, "include", 7))
188        {
189          // We have a #include statement
190
191          ptr += 7;
192
193          while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
194         
195          if (*ptr == '<')
196            {
197              term = '>';
198              ptr++;
199            }
200          else if (*ptr == '"')
201            {
202              term = '"';
203              ptr++;
204            }
205          else
206            {
207              // empty #include statement??
208              state = in_line;
209              ptr += strlen (ptr);
210              return (ptr);
211            }
212        }
213      else
214        {
215          // ignore other pre-processor statements
216
217          state = in_line;
218          ptr += strlen (ptr);
219          return (ptr);
220        }
221    }
222  else if (!strncmp (ptr, "      include", 13))
223    {
224      // fortran include statement
225
226      ptr += 13;
227
228      while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
229
230      if (*ptr == '\'')
231        {
232          term = '\'';
233          ptr++;
234        }
235      else
236        {
237          state = in_line;
238          return (ptr);
239        }
240    }
241  else if (!strncmp (ptr, "\tinclude", 8))
242    {
243      // fortran include statement
244
245      ptr += 8;
246
247      while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
248
249      if (*ptr == '\'')
250        {
251          term = '\'';
252          ptr++;
253        }
254      else
255        {
256          state = in_line;
257          return (ptr);
258        }
259    }
260  else
261    {
262      state = in_line;
263      return (ptr);
264    }
265
266  // At this point we do have to include a header file.
267
268  char* end;
269
270  end = strchr (ptr, term);
271  if (end != 0)
272    {
273      *end = 0;
274    }
275 
276  const char* header_file = ptr;
277 
278  header_file_action (header_file,
279                      dir_name,
280                      current_path_index,
281                      include_paths,
282                      substitutions,
283                      header_filters,
284                      all_deps,
285                      deps);
286 
287  if (end != 0)
288    {
289      *end = term;
290    }
291
292  state = in_line;
293  ptr += strlen (ptr);
294 
295  return (ptr);
296}
297
298/**
299   Any line with no header inclusion
300   step through comments and strings
301*/
302static char* in_line_action (char* ptr, state_def& state)
303{
304  char* pattern = ptr + strlen (ptr);
305  int length = 0;
306
307  /*
308    search for the first occurrence of
309    {single-quote double-quote open-comment open-line-comment}
310
311    Must exclude escaped quotes \' and \"
312  */
313
314  char* pos = strchr (ptr, '"');
315  if ((pos != 0) && (pos < pattern) && (pos > ptr) && (*(pos-1) != '\\'))
316    {
317      state = in_string;
318      pattern = pos;
319      length = 1;
320    }
321
322  pos = strchr (ptr, '\'');
323  if ((pos != 0) && (pos < pattern) && (pos > ptr) && (*(pos-1) != '\\'))
324    {
325      state = in_char;
326      pattern = pos;
327      length = 1;
328    }
329
330  pos = strstr (ptr, "/*");   //*/
331  if ((pos != 0) && (pos < pattern))
332    {
333      state = in_comment;
334      pattern = pos;
335      length = 2;
336    }
337
338  pos = strstr (ptr, "//");
339  if ((pos != 0) && (pos < pattern))
340    {
341      state = in_line_comment;
342      pattern = pos;
343      length = 2;
344    }
345
346  ptr = pattern + length;
347
348  return (ptr);
349}
350
351//--------------------------------------------------
352static char* in_string_action (char* ptr, state_def& state)
353{
354  // we exclusively look for a double quote
355
356  char* pos = strchr (ptr, '"');
357  if (pos == 0)
358    {
359      // This string is not finished till the end of the line..
360      // we expect it to continue to the next line...
361      // thus we leave the state as it is
362      ptr += strlen (ptr);
363    }
364  else
365    {
366      if ((pos > ptr) && (*(pos - 1) == '\\'))
367        {
368          ptr = pos + 1;
369        }
370      else
371        {
372          ptr = pos + 1;
373          state = in_line;
374        }
375    }
376
377  return (ptr);
378}
379
380//--------------------------------------------------
381static char* in_char_action (char* ptr, state_def& state)
382{
383  // we exclusively look for a single quote
384
385  char* pos = strchr (ptr, '\'');
386  if (pos == 0)
387    {
388      // This string is not finished till the end of the line..
389      // we expect it continues to the nex line...
390      // thus we leave the state as it is
391      ptr += strlen (ptr);
392    }
393  else
394    {
395      if ((pos > ptr) && (*(pos - 1) == '\\'))
396        {
397          ptr = pos + 1;
398        }
399      else
400        {
401          ptr = pos + 1;
402          state = in_line;
403        }
404    }
405
406  return (ptr);
407}
408
409//--------------------------------------------------
410static char* in_comment_action (char* ptr, state_def& state)
411{
412  char* pattern = ptr + strlen (ptr);
413  int length    = 0;
414  char* pos;
415 
416
417  /*
418    Even if we are inside a comment, we must detect strings since comment markers may
419    be written inside them.
420 
421    pos = strchr (ptr, '"');
422 
423    if ((pos != 0) && (pos < pattern) && (pos > ptr) && (*(pos-1) != '\\'))
424    {
425    state = in_string_comment;
426    pattern = pos;
427    length = 1;
428    }
429
430    pos = strchr (ptr, '\'');
431    if ((pos != 0) && (pos < pattern) && (pos > ptr) && (*(pos-1) != '\\'))
432    {
433    state = in_char_comment;
434    pattern = pos;
435    length = 1;
436    }
437  */
438  pos = strstr (ptr, "*/");
439  if ((pos != 0) && (pos < pattern))
440    {
441      state   = in_line;
442      pattern = pos;
443      length  = 2;
444    }
445
446  ptr = pattern + length;
447
448  return (ptr);
449}
450
451//--------------------------------------------------
452static char* in_string_comment_action (char* ptr, state_def& state)
453{
454  char* pos = strchr (ptr, '"');
455  if (pos == 0)
456    {
457      // This string is not finished till the end of the line..
458      // we expect it continues to the nex line...
459      ptr += strlen (ptr);
460    }
461  else
462    {
463      if ((pos > ptr) && (*(pos - 1) == '\\'))
464        {
465          ptr = pos + 1;
466        }
467      else
468        {
469          ptr = pos + 1;
470          state = in_comment;
471        }
472    }
473
474  return (ptr);
475}
476
477//--------------------------------------------------
478static char* in_char_comment_action (char* ptr, state_def& state)
479{
480  char* pos = strchr (ptr, '\'');
481  if (pos == 0)
482    {
483      // This string is not finished till the end of the line..
484      // we expect it continues to the nex line...
485      ptr += strlen (ptr);
486    }
487  else
488    {
489      if ((pos > ptr) && (*(pos - 1) == '\\'))
490        {
491          ptr = pos + 1;
492        }
493      else
494        {
495          ptr = pos + 1;
496          state = in_comment;
497        }
498      pos--;
499    }
500
501  return (ptr);
502}
503
504//--------------------------------------------------
505static char* in_line_comment_action (char* ptr, state_def& state)
506{
507  char * pos = strchr (ptr, '\\'); 
508  /* Extend this part to deal with continuation character */ 
509  if ( (pos == NULL) || ( (ptr + strlen(ptr)-1)!=pos ))
510    {
511      state = in_line;
512    }
513 
514  ptr    += strlen (ptr);
515 
516  return (ptr);
517}
518
519//--------------------------------------------------
520static void build_deps_text (char* text,
521                             const cmt_string& dir_name,
522                             int current_path_index,
523                             const CmtSystem::cmt_string_vector& include_paths,
524                             const CmtSystem::cmt_string_vector& substitutions,
525                             const DepsBuilder::HeaderFilters& header_filters,
526                             CmtSystem::cmt_string_vector& all_deps,
527                             CmtSystem::cmt_string_vector& deps)
528{
529  Log;
530
531  int pos;
532  int max_pos;
533  int line_number = 1;
534
535  log << "CMT> build_deps_text dir_name="
536      << dir_name << log_endl;
537
538  // erase of continuation character
539  pos = 0;
540  max_pos = strlen (text);
541  char* current = text;
542
543  char* last = text + max_pos;
544  while (current < last)
545    {
546   
547      //  bscrnl -> BackSlash Carriage Return New Line
548      //  bsnl -> BackSlash New Line
549      char* bscrnl = strstr (current, "\\\r\n");
550      char* bsnl   = strstr (current, "\\\n");
551     
552      if ( (bscrnl==0) && (bsnl ==0)) break;
553     
554      int length = 0;
555           
556      char * ptr = 0;
557      if (bsnl==0)  //bscrnl > 0
558        {
559          length = 3;
560          ptr    = bscrnl; 
561        }     
562      else if (bscrnl==0) //bsnl > 0
563        {
564          length = 2;                       
565          ptr    = bsnl; 
566        }     
567      else if (bscrnl < bsnl)
568        {
569          length = 3;
570          ptr    = bscrnl;                 
571        }
572      else // (bscrnl > bsnl)
573        {
574          length = 2;                       
575          ptr    = bsnl;         
576        }
577      strcpy (ptr, ptr+length);
578      current = ptr;
579      last -= length;
580    } 
581 
582  pos = 0;
583  max_pos = strlen (text);
584  current = text;
585  last = text + max_pos;
586
587  state_def state = at_start;
588 
589
590  while (current < last)
591    {
592             
593      char marker;
594      char* marker_pos = 0;
595
596      //  crnl -> Carriage Return New Line
597      //  nl -> New Line
598      char* crnl = strstr (current, "\r\n");
599      char* nl = strchr (current, '\n');
600
601      char* first = nl;
602      int length = 1;
603
604      char* ptr = 0;
605
606      if (crnl != 0)
607        {
608          // cr+nl has been found
609
610          if (nl == 0)
611            {
612              // cr but no nl ??
613              first = crnl;
614              length = 2;
615            }
616          else
617            {
618              // both cr+nl and nl found
619              first = (nl < crnl) ? nl : crnl;
620              length = (nl < crnl) ? 1 : 2;
621            }
622        }
623      else
624        {
625          // no cr+nl but nl alone found
626          first = nl;
627          length = 1;
628        }
629
630      ptr = current;
631
632      if (first == 0)
633        {
634          // neither nl nor cr+nl found => this is the last line
635          marker_pos = 0;
636        }
637      else
638        {
639          marker_pos = first;
640          marker = *marker_pos;
641          *marker_pos = 0;
642        }
643
644      log << "CMT> build_deps_text2 line=[" 
645          << current << "]" << log_endl;
646     
647      while (strlen (ptr) > 0)
648        {
649          switch (state)
650            {
651            case at_start:
652              ptr = at_start_action (ptr,
653                                     state,
654                                     dir_name,
655                                     current_path_index,
656                                     include_paths,
657                                     substitutions,
658                                     header_filters,
659                                     all_deps,
660                                     deps);
661              break;
662            case in_line:
663              ptr = in_line_action (ptr, state);
664              break;
665            case in_string:
666              ptr = in_string_action (ptr, state);
667              break;
668            case in_char:
669              ptr = in_char_action (ptr, state);
670              break;
671            case in_comment:
672              ptr = in_comment_action (ptr, state);
673              break;
674            case in_string_comment:
675              ptr = in_string_comment_action (ptr, state);
676              break;
677            case in_char_comment:
678              ptr = in_char_comment_action (ptr, state);
679              break;
680            case in_line_comment:
681              ptr = in_line_comment_action (ptr, state);
682              break;
683            }
684        }
685
686      if (state == in_line) state = at_start;
687      line_number++;
688
689      if (marker_pos != 0)
690        {
691          *marker_pos = marker;
692          current = marker_pos + length;
693        }
694      else
695        {
696          break;
697        }
698    }
699           
700}
701
702//--------------------------------------------------
703static int build_deps (const cmt_string& name,
704                       const cmt_string& dir_name,
705                       int current_path_index,
706                       const CmtSystem::cmt_string_vector& include_paths,
707                       const CmtSystem::cmt_string_vector& substitutions,
708                       const DepsBuilder::HeaderFilters& header_filters,
709                       CmtSystem::cmt_string_vector& all_deps,
710                       CmtSystem::cmt_string_vector& deps)
711{
712  Log;
713
714  log << "CMT> build_deps name=" << name << " dir_name=" 
715      << dir_name << log_endl;
716
717  cmt_string full_name;
718  int path_index = locate (name,
719                           dir_name,
720                           include_paths,
721                           substitutions,
722                           full_name);
723
724  if (path_index >= 0)
725    {
726      cmt_string text;
727      text.read (full_name);
728      char* ptr = &text[0];
729      cmt_string new_dir;
730      CmtSystem::dirname (full_name, new_dir);
731
732      if (path_index == 0 || path_index == 1)
733        build_deps_text (ptr, new_dir,
734                         current_path_index,
735                         include_paths, substitutions,
736                         header_filters,
737                         all_deps, deps);
738      else
739        build_deps_text (ptr, new_dir,
740                         path_index,
741                         include_paths, substitutions,
742                         header_filters,
743                         all_deps, deps);
744    }
745  if (path_index < 0)
746    {
747      log << "CMT> build_deps3" << log_endl;
748    }
749  return path_index;
750}
751
752//--------------------------------------------------
753static int locate (const cmt_string& name,
754                   const cmt_string& dir_name,
755                   const CmtSystem::cmt_string_vector& include_paths,
756                   const CmtSystem::cmt_string_vector& substitutions,
757                   cmt_string& full_name)
758{
759  Log;
760
761  log << "CMT> locate name=" << name << " dir_name=" 
762      << dir_name << log_endl;
763
764  //
765  // Return 0 when the file is found in the current directory
766  //
767  if (CmtSystem::test_file (name))
768    {
769      full_name = name;
770      return (0);
771    }
772
773  cmt_string p;
774
775  //
776  // Return 1 when the file is found in the directory of the
777  // upper level source file
778  //
779  p = dir_name;
780  p += CmtSystem::file_separator ();
781  p += name;
782  if (CmtSystem::test_file (p))
783    {
784      full_name = p;
785      return (1);
786    }
787
788  //
789  // Return [path_index + 2] when the include file is found at one of
790  // the include_paths
791  //
792  for (int path_index = 0; path_index < include_paths.size (); path_index++)
793    {
794      p  = include_paths[path_index];
795      p += CmtSystem::file_separator ();
796      p += name;
797
798      log << "CMT> locate2 full_name=" << p << log_endl;
799
800      if (CmtSystem::test_file (p))
801        {
802          full_name = p;
803          return (path_index + 2);
804        }
805    }
806
807  log << "CMT> locate3" << log_endl;
808
809  return (-1);
810}
811
812//--------------------------------------------------------------------------
813void DepsBuilder::clear ()
814{
815  m_include_paths.clear ();
816  m_substitutions.clear ();
817  for (int i = m_header_filters.size () - 1; i >= 0; i--)
818    {
819      m_header_filters[i].clear ();
820    }
821  m_header_filters.clear ();
822}
823
824//--------------------------------------------------------------------------
825void DepsBuilder::add (const cmt_string& path, const cmt_string& substitution)
826{
827  if (path.size () == 0)
828    {
829      return;
830    }
831  if (path[path.size () - 1] == CmtSystem::file_separator ())
832    {
833      cmt_string p = path;
834      p.erase (path.size () - 1);
835      m_include_paths.push_back (p);
836    }
837  else
838    {
839      m_include_paths.push_back (path);
840    }
841
842  m_substitutions.push_back (substitution);
843}
844
845//--------------------------------------------------------------------------
846void DepsBuilder::add_includes (const Use& use)
847{
848  Log;
849
850  const Include::IncludeVector& includes = use.includes;
851  int include_number;
852
853  for (include_number = 0;
854       include_number < includes.size ();
855       include_number++)
856    {
857      const Include& include = includes[include_number];
858
859      cmt_string temp = include.name;
860      cmt_string pattern;
861      cmt_string name;
862      char end_pattern;
863
864      int start = 0;
865
866      for (;;)
867        {
868          int begin;
869
870          begin = temp.find (start, "${");
871          if (begin != cmt_string::npos)
872            {
873              end_pattern = '}';
874            }
875          else
876            {
877              begin = temp.find (start, "$(");
878              if (begin != cmt_string::npos)
879                {
880                  end_pattern = ')';
881                }
882              else
883                {
884                  break;
885                }
886            }
887
888          start = begin + 2;
889
890          int end;
891          end = temp.find (start, end_pattern);
892          if (end == cmt_string::npos) break;
893          if (end < begin) break;
894          start = end + 1;
895
896          temp.substr (begin, end - begin + 1, pattern);
897          temp.substr (begin + 2, end - begin - 2, name);
898
899          Symbol* macro = Symbol::find (name);
900          if (macro != 0)
901            {
902              cmt_string value = macro->resolve_macro_value ();
903              value += CmtSystem::file_separator ();
904              temp.replace_all (pattern, value);
905            }
906          else
907            {
908              cmt_string value = CmtSystem::getenv (name);
909              value += CmtSystem::file_separator ();
910              temp.replace_all (pattern, value);
911            }
912        }
913
914      log << "include = " << temp << log_endl;
915
916      add (temp, include.name);
917    }
918}
919
920//--------------------------------------------------------------------------
921CmtSystem::cmt_string_vector& DepsBuilder::run (const cmt_string& file_name)
922{
923  Log;
924
925  log << "Starting deps builder on " << file_name << log_endl;
926
927  m_deps.clear ();
928  m_all_deps.clear ();
929
930  cmt_string preprocessor;
931  Symbol* macro = Symbol::find ("preprocessor_command");
932  if (macro != 0)
933    {
934      preprocessor = macro->resolve_macro_value ();
935    }
936
937  if (preprocessor == "")
938    {
939      //
940      //   Since no preprocessor command is defined,
941      // we use the internal mechanism provided here.
942      //
943      cmt_string new_dir;
944
945      CmtSystem::dirname (file_name, new_dir);
946
947      build_deps (file_name,
948                  new_dir,
949                  0,
950                  m_include_paths,
951                  m_substitutions,
952                  m_header_filters,
953                  m_all_deps,
954                  m_deps);
955    }
956  else
957    {
958      //
959      //  An external preprocessor command is defined. We expect it
960      // to follow a "standard" syntax for its output, ie:
961      //   o It starts with:
962      //       <module>.o: ...
963      //   o There may be many lines with trailing back-slashes
964      //   o All entries are space-separated
965      //   o One of the entries is the source file name itself
966      //
967      //  The preprocessor command expects the list of -I options
968      // (resolved from the "includes" macro) and the list of
969      // -D/-U options (resolved from the "*_pp_*flags" macros)
970      //
971
972      //
973      // Building the complete command (still the pp_*flags are
974      // missing)
975      //
976      preprocessor += " ";
977      macro = Symbol::find ("includes");
978      preprocessor += macro->resolve_macro_value ();
979      preprocessor += " ";
980      preprocessor += file_name;
981     
982      cmt_string output;
983     
984      CmtSystem::execute (preprocessor, output);
985
986      //
987      // Make the output as one single big line.
988      //
989
990      output.replace_all ("\n", " ");
991      output.replace_all ("\\ ", " ");
992     
993      CmtSystem::cmt_string_vector files;
994     
995      CmtSystem::split (output, " \t", files);
996
997      //
998      // Analyze each entry
999      //
1000     
1001      for (int i = 1; i < files.size (); i++)
1002        {
1003          const cmt_string& file = files[i];
1004          if (file == file_name) continue;
1005         
1006          cmt_string dir;
1007          cmt_string name;
1008          cmt_string full_name;
1009         
1010          CmtSystem::dirname (file, dir);
1011
1012          //
1013          // Only declared include_paths will be taken into account
1014          // Others are considered as system include paths.
1015          //
1016         
1017          for (int j = 0; j < m_include_paths.size (); j++)
1018            {
1019              const cmt_string& p = m_include_paths[j];
1020              if (dir == p)
1021                {
1022                  CmtSystem::basename (file, name);
1023                  full_name = m_substitutions[j];
1024                  full_name += name;
1025
1026                  //
1027                  // We add in the "m_deps" list the symbolic form
1028                  // of the path rather that the expanded one.
1029                  //
1030                 
1031                  m_deps.push_back (full_name);
1032                 
1033                  break;
1034                }
1035            }
1036        }
1037    }
1038
1039  return (m_deps);
1040}
1041
1042//--------------------------------------------------------------------------
1043void DepsBuilder::add_header_filter (const Use* use, const cmt_regexp* filter, const cmt_string& stamp)
1044{
1045  add_header_filter (HeaderFilter (use, filter, stamp));
1046}
1047
1048//--------------------------------------------------------------------------
1049void DepsBuilder::add_header_filter (const HeaderFilter& hf)
1050{
1051  m_header_filters.push_back (hf);
1052}
Note: See TracBrowser for help on using the repository browser.