Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 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 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Beres, Szabolcs | |
11 | * | |
12 | ******************************************************************************/ | |
970ed795 EL |
13 | #ifndef CFG_PROCESS_UTILS_HH_ |
14 | #define CFG_PROCESS_UTILS_HH_ | |
15 | ||
16 | ||
17 | #include <deque> | |
18 | #include <string> | |
19 | ||
20 | #include "Path2.hh" | |
21 | ||
22 | template <typename T_BUFFER_STATE> | |
23 | class IncludeElem { | |
24 | public: | |
25 | std::string dir; | |
26 | std::string fname; | |
27 | FILE* fp; | |
28 | T_BUFFER_STATE buffer_state; | |
29 | int line_number; | |
30 | ||
31 | ||
32 | IncludeElem(const std::string& fname_) | |
33 | : dir(Path::get_dir(fname_)), fname(Path::get_file(fname_)), | |
34 | fp(NULL), buffer_state(NULL), line_number(-1) { } | |
35 | ||
36 | IncludeElem(const std::string& fname_, FILE* fp_) | |
37 | : dir(Path::get_dir(fname_)), fname(Path::get_file(fname_)), | |
38 | fp(fp_), buffer_state(NULL), line_number(-1) { } | |
39 | ||
40 | bool equals(const std::string& path) const { | |
41 | return Path::compose(dir, fname) == path; | |
42 | } | |
43 | ||
44 | std::string get_full_path() const { | |
45 | return Path::compose(dir, fname); | |
46 | } | |
47 | ||
48 | }; | |
49 | ||
50 | template <typename T_BUFFER_STATE> | |
51 | std::string dump_include_chain(const std::deque<IncludeElem<T_BUFFER_STATE> >& chain) { | |
52 | ||
53 | std::string result; | |
54 | if (chain.empty()) { | |
55 | return result; | |
56 | } | |
57 | ||
58 | typename std::deque<IncludeElem<T_BUFFER_STATE> >::const_iterator it = chain.begin(); | |
59 | result.append(it->dir).append(it->fname); | |
60 | for (++it; it != chain.end(); ++it) { | |
61 | result.append("->"); | |
62 | result.append(it->dir).append(it->fname); | |
63 | } | |
64 | return result; | |
65 | } | |
66 | ||
67 | template <typename T_BUFFER_STATE> | |
68 | std::string switch_lexer(std::deque<IncludeElem<T_BUFFER_STATE> >* p_include_chain, | |
69 | const std::string& include_file, T_BUFFER_STATE p_current_buffer, | |
70 | T_BUFFER_STATE (*p_yy_create_buffer)(FILE*, int), | |
71 | void (*p_yy_switch_to_buffer)(T_BUFFER_STATE), | |
72 | int p_current_line, int p_buf_size) { | |
73 | ||
74 | if (include_file.empty()) { | |
75 | return std::string("Empty file name."); | |
76 | } | |
77 | ||
78 | std::string abs_path; | |
79 | if (Path::is_absolute(include_file)) { | |
80 | abs_path = include_file; | |
81 | } else { | |
82 | abs_path = Path::normalize(Path::compose(p_include_chain->back().dir, include_file)); | |
83 | } | |
84 | ||
85 | for (typename std::deque<IncludeElem<T_BUFFER_STATE> >::iterator it = p_include_chain->begin(); | |
86 | it != p_include_chain->end(); ++it) { | |
87 | if (it->equals(abs_path)) { | |
88 | p_include_chain->push_back(IncludeElem<T_BUFFER_STATE>(abs_path)); | |
89 | std::string error_msg("Circular import chain detected:\n"); | |
90 | error_msg.append(dump_include_chain(*p_include_chain)); | |
91 | p_include_chain->pop_back(); | |
92 | return error_msg; | |
93 | } | |
94 | } | |
95 | ||
96 | p_include_chain->back().buffer_state = p_current_buffer; | |
97 | p_include_chain->back().line_number = p_current_line; | |
98 | ||
99 | FILE* fp = fopen(abs_path.c_str(), "r"); | |
100 | if (!fp) { | |
101 | std::string error_msg("File not found: "); | |
102 | error_msg.append(abs_path); | |
103 | return error_msg; | |
104 | } | |
105 | ||
106 | IncludeElem<T_BUFFER_STATE> new_elem(abs_path, fp); | |
107 | p_include_chain->push_back(new_elem); | |
108 | new_elem.buffer_state = p_yy_create_buffer(fp, p_buf_size); | |
109 | p_yy_switch_to_buffer(new_elem.buffer_state); | |
110 | return std::string(""); | |
111 | } | |
112 | ||
113 | #endif |