Sync with 5.1.0
[deliverable/titan.core.git] / common / cfg_process_utils.hh
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #ifndef CFG_PROCESS_UTILS_HH_
9 #define CFG_PROCESS_UTILS_HH_
10
11
12 #include <deque>
13 #include <string>
14
15 #include "Path2.hh"
16
17 template <typename T_BUFFER_STATE>
18 class IncludeElem {
19 public:
20 std::string dir;
21 std::string fname;
22 FILE* fp;
23 T_BUFFER_STATE buffer_state;
24 int line_number;
25
26
27 IncludeElem(const std::string& fname_)
28 : dir(Path::get_dir(fname_)), fname(Path::get_file(fname_)),
29 fp(NULL), buffer_state(NULL), line_number(-1) { }
30
31 IncludeElem(const std::string& fname_, FILE* fp_)
32 : dir(Path::get_dir(fname_)), fname(Path::get_file(fname_)),
33 fp(fp_), buffer_state(NULL), line_number(-1) { }
34
35 bool equals(const std::string& path) const {
36 return Path::compose(dir, fname) == path;
37 }
38
39 std::string get_full_path() const {
40 return Path::compose(dir, fname);
41 }
42
43 };
44
45 template <typename T_BUFFER_STATE>
46 std::string dump_include_chain(const std::deque<IncludeElem<T_BUFFER_STATE> >& chain) {
47
48 std::string result;
49 if (chain.empty()) {
50 return result;
51 }
52
53 typename std::deque<IncludeElem<T_BUFFER_STATE> >::const_iterator it = chain.begin();
54 result.append(it->dir).append(it->fname);
55 for (++it; it != chain.end(); ++it) {
56 result.append("->");
57 result.append(it->dir).append(it->fname);
58 }
59 return result;
60 }
61
62 template <typename T_BUFFER_STATE>
63 std::string switch_lexer(std::deque<IncludeElem<T_BUFFER_STATE> >* p_include_chain,
64 const std::string& include_file, T_BUFFER_STATE p_current_buffer,
65 T_BUFFER_STATE (*p_yy_create_buffer)(FILE*, int),
66 void (*p_yy_switch_to_buffer)(T_BUFFER_STATE),
67 int p_current_line, int p_buf_size) {
68
69 if (include_file.empty()) {
70 return std::string("Empty file name.");
71 }
72
73 std::string abs_path;
74 if (Path::is_absolute(include_file)) {
75 abs_path = include_file;
76 } else {
77 abs_path = Path::normalize(Path::compose(p_include_chain->back().dir, include_file));
78 }
79
80 for (typename std::deque<IncludeElem<T_BUFFER_STATE> >::iterator it = p_include_chain->begin();
81 it != p_include_chain->end(); ++it) {
82 if (it->equals(abs_path)) {
83 p_include_chain->push_back(IncludeElem<T_BUFFER_STATE>(abs_path));
84 std::string error_msg("Circular import chain detected:\n");
85 error_msg.append(dump_include_chain(*p_include_chain));
86 p_include_chain->pop_back();
87 return error_msg;
88 }
89 }
90
91 p_include_chain->back().buffer_state = p_current_buffer;
92 p_include_chain->back().line_number = p_current_line;
93
94 FILE* fp = fopen(abs_path.c_str(), "r");
95 if (!fp) {
96 std::string error_msg("File not found: ");
97 error_msg.append(abs_path);
98 return error_msg;
99 }
100
101 IncludeElem<T_BUFFER_STATE> new_elem(abs_path, fp);
102 p_include_chain->push_back(new_elem);
103 new_elem.buffer_state = p_yy_create_buffer(fp, p_buf_size);
104 p_yy_switch_to_buffer(new_elem.buffer_state);
105 return std::string("");
106 }
107
108 #endif
This page took 0.032595 seconds and 5 git commands to generate.