|
5 | 5 | #include<cstdlib> |
6 | 6 | #include<filesystem> |
7 | 7 | #include<algorithm> |
| 8 | +#include<regex> |
8 | 9 |
|
9 | 10 | #include"c-main-generator.h" |
10 | 11 |
|
11 | 12 | staticconstsize_tkMaxDirNum =1000; |
12 | 13 |
|
13 | 14 | staticconstsize_tkWBUFF_len =2048; |
14 | | -staticchar wbuff[kWBUFF_len] = {0 }; |
| 15 | +staticchar wbuff[kWBUFF_len] = {0}; |
| 16 | + |
| 17 | +static std::string __typeprint[] = |
| 18 | +{ |
| 19 | +"int8_t", |
| 20 | +"int16_t", |
| 21 | +"int32_t", |
| 22 | +"int64_t", |
| 23 | +"uint8_t", |
| 24 | +"uint16_t", |
| 25 | +"uint32_t", |
| 26 | +"uint64_t" |
| 27 | +}; |
| 28 | + |
| 29 | +std::stringstr_toupper(std::string s) |
| 30 | +{ |
| 31 | +std::transform(s.begin(), s.end(), s.begin(), |
| 32 | + [](unsignedchar c) |
| 33 | + { |
| 34 | +returnstd::toupper(c); |
| 35 | + }); |
| 36 | +return s; |
| 37 | +} |
15 | 38 |
|
16 | 39 | CiMainGenerator::CiMainGenerator() |
17 | 40 | { |
18 | 41 | sigprt =new CSigPrinter; |
| 42 | + fwriter =new FileWriter; |
19 | 43 | } |
20 | 44 |
|
21 | | -voidCiMainGenerator::Generate(std::vector<MessageDescriptor_t*>& msgs, std::string drvname, std::string dirpath) |
| 45 | +voidCiMainGenerator::Generate(std::vector<MessageDescriptor_t*>& msgs, |
| 46 | + std::string drvname, |
| 47 | + std::string dirpath) |
22 | 48 | { |
23 | | -// Load income messages to sig printer |
| 49 | +// Load income messages to sig printer |
24 | 50 | sigprt->LoadMessages(msgs); |
25 | 51 |
|
26 | 52 | std::sort(sigprt->sigs_expr.begin(), sigprt->sigs_expr.end(), |
27 | | - [](const CiExpr_t* a,const CiExpr_t* b) ->bool |
28 | | - { |
29 | | -return a->msg.MsgID < b->msg.MsgID; |
30 | | - }); |
| 53 | + [](const CiExpr_t* a,const CiExpr_t* b) ->bool |
| 54 | + { |
| 55 | +return a->msg.MsgID < b->msg.MsgID; |
| 56 | + }); |
| 57 | + |
| 58 | +auto dirok =SetFinalPath(dirpath); |
| 59 | + |
| 60 | +if (!dirok) |
| 61 | + { |
| 62 | +// TODO: handle error if directory cannot be used |
| 63 | + } |
| 64 | + |
| 65 | +SetCommonValues(drvname); |
| 66 | + |
| 67 | +// work_dir_path has the base dir path to gen files |
| 68 | + mhead.dir = work_dir_path; |
| 69 | + mhead.fname = drvname +".h"; |
| 70 | + mhead.fpath = mhead.dir +"/" + mhead.fname; |
31 | 71 |
|
32 | | -SetFinalPath(dirpath); |
33 | 72 | // 1 step is to define final directory for source code bunch |
| 73 | + fwriter->AppendLine("#pragma once",3); |
| 74 | + fwriter->AppendLine("#ifdef __cplusplus\nextern\"C\" {\n#endif",2); |
| 75 | + fwriter->AppendLine("#include <stdint.h>"); |
| 76 | + |
| 77 | +for (size_t num =0; num < sigprt->sigs_expr.size(); num++) |
| 78 | + { |
| 79 | +// write message typedef s and additional expressions |
| 80 | + MessageDescriptor_t& m = sigprt->sigs_expr[num]->msg; |
| 81 | + |
| 82 | +snprintf(wbuff,kWBUFF_len,"// def @%s CAN Message (%-4d %#x)", m.Name.c_str(), m.MsgID, m.MsgID); |
| 83 | + fwriter->AppendLine(wbuff); |
| 84 | +snprintf(wbuff,kWBUFF_len,"#define %s_IDE (%uU)", m.Name.c_str(), m.IsExt); |
| 85 | + fwriter->AppendLine(wbuff); |
| 86 | +snprintf(wbuff,kWBUFF_len,"#define %s_DLC (%uU)", m.Name.c_str(), m.DLC); |
| 87 | + fwriter->AppendLine(wbuff); |
| 88 | +snprintf(wbuff,kWBUFF_len,"#define %s_CANID (%#x)", m.Name.c_str(), m.MsgID); |
| 89 | + fwriter->AppendLine(wbuff); |
| 90 | + |
| 91 | +if (m.Cycle >0) |
| 92 | + { |
| 93 | +snprintf(wbuff,kWBUFF_len,"#define %s_CYC (%dU)", m.Name.c_str(), m.Cycle); |
| 94 | + fwriter->AppendLine(wbuff); |
| 95 | + } |
| 96 | + |
| 97 | +if (m.CommentText.size() >0) |
| 98 | + { |
| 99 | + fwriter->AppendLine("// --" + m.CommentText); |
| 100 | + } |
| 101 | + |
| 102 | +size_t max_sig_name_len =27; |
| 103 | + |
| 104 | +for (size_t signum =0; signum < m.Signals.size(); signum++) |
| 105 | + { |
| 106 | + SignalDescriptor_t& s = m.Signals[signum]; |
| 107 | + |
| 108 | +// TODO: print signal to_S and from_S definitions if necessary |
| 109 | +//string ret = cprint.PrintSignalPackExpression(sig, msg.MessageName); |
| 110 | + |
| 111 | +//if (ret != null) |
| 112 | +//{ |
| 113 | +// fwriter->AppendLine(ret); |
| 114 | +//} |
| 115 | +if (s.Name.size() > max_sig_name_len) |
| 116 | + max_sig_name_len = s.Name.size(); |
| 117 | + } |
| 118 | + |
| 119 | +snprintf(wbuff,kWBUFF_len,"typedef struct"); |
| 120 | + fwriter->AppendLine(wbuff); |
| 121 | + |
| 122 | + fwriter->AppendLine("{\n"); |
| 123 | + |
| 124 | +// Write section for bitfielded part |
| 125 | +snprintf(wbuff,kWBUFF_len,"#ifdef %s", usebits_str.c_str()); |
| 126 | + fwriter->AppendLine(wbuff,2); |
| 127 | + |
| 128 | +for (size_t signum =0; signum < m.Signals.size(); signum++) |
| 129 | + { |
| 130 | + SignalDescriptor_t& sig = m.Signals[signum]; |
| 131 | +// Write bit-fielded part |
| 132 | +WriteSigStructField(sig,true, max_sig_name_len); |
| 133 | + } |
| 134 | + |
| 135 | +// Write clean part |
| 136 | + fwriter->AppendLine("#else",2); |
| 137 | + |
| 138 | +for (size_t signum =0; signum < m.Signals.size(); signum++) |
| 139 | + { |
| 140 | + SignalDescriptor_t& sig = m.Signals[signum]; |
| 141 | +// Write clean signals |
| 142 | +WriteSigStructField(sig,false, max_sig_name_len); |
| 143 | + } |
| 144 | + |
| 145 | +snprintf(wbuff,kWBUFF_len,"#endif // %s", usebits_str.c_str()); |
| 146 | + fwriter->AppendLine(wbuff,2); |
34 | 147 |
|
| 148 | +//if (CodeSett.Code.UseMonitors == 1) |
| 149 | +// fwriter->AppendLine(" FrameMonitor_t mon1;"); |
| 150 | + |
| 151 | +snprintf(wbuff,kWBUFF_len,"} %s_t;", m.Name.c_str()); |
| 152 | + fwriter->AppendLine(wbuff,2); |
| 153 | +//fwriter->AppendLine("} " + msg.MessageName + "_t;"); |
| 154 | +//fwriter->AppendLine(); |
| 155 | + } |
| 156 | + |
| 157 | + fwriter->AppendLine("#ifdef __cplusplus\n}\n#endif"); |
| 158 | + fwriter->Flush(mhead.fpath); |
35 | 159 | // 2 step is to print main head file |
36 | | -
|
| 160 | + |
37 | 161 | // 3 step is to print main source file |
38 | 162 |
|
39 | 163 | // 4 step is to pring fmon head file |
40 | 164 |
|
41 | 165 | // 5 step is to print fmon source file |
| 166 | +} |
| 167 | + |
| 168 | +voidCiMainGenerator::WriteSigStructField(const SignalDescriptor_t& sig,bool bits,size_t padwidth) |
| 169 | +{ |
| 170 | +if (sig.CommentText.size() >0) |
| 171 | + { |
| 172 | + fwriter->AppendLine(" //" +std::regex_replace(sig.CommentText,std::regex("\n"),"\n //")); |
| 173 | + } |
| 174 | + |
| 175 | +if (sig.ValueText.size() >0) |
| 176 | + { |
| 177 | + fwriter->AppendLine(" //" +std::regex_replace(sig.ValueText,std::regex("\n"),"\n //")); |
| 178 | + } |
| 179 | + |
| 180 | + std::string dtype =""; |
| 181 | + |
| 182 | + dtype +="" + __typeprint[(int)sig.Type] +"" + sig.Name; |
| 183 | + |
| 184 | +if (bits && (sig.LengthBit <8)) |
| 185 | + { |
| 186 | +snprintf(wbuff,kWBUFF_len," : %d", sig.LengthBit); |
| 187 | + dtype += wbuff; |
| 188 | + } |
| 189 | + |
| 190 | + dtype +=";"; |
| 191 | + |
| 192 | + std::string pad =""; |
| 193 | + |
| 194 | + dtype += pad.insert(0, padwidth +16 - dtype.size(),''); |
42 | 195 |
|
| 196 | + fwriter->AppendText(dtype); |
| 197 | + |
| 198 | + pad =" //"; |
| 199 | + pad += (sig.Signed) ?" [-]" :""; |
| 200 | + |
| 201 | + fwriter->AppendText(pad); |
| 202 | + |
| 203 | +snprintf(wbuff,kWBUFF_len," Bits=%2d", sig.LengthBit); |
| 204 | + fwriter->AppendText(wbuff); |
| 205 | + |
| 206 | +if (sig.Unit.size() >0) |
| 207 | + { |
| 208 | +snprintf(wbuff,kWBUFF_len," Unit:'%-13s'", sig.Unit.c_str()); |
| 209 | + fwriter->AppendText(wbuff); |
| 210 | + } |
| 211 | + |
| 212 | +if (sig.Offset !=0) |
| 213 | + { |
| 214 | +snprintf(wbuff,kWBUFF_len," Offset= %-18f", sig.Offset); |
| 215 | + fwriter->AppendText(wbuff); |
| 216 | + } |
| 217 | + |
| 218 | +if (sig.Factor !=1) |
| 219 | + { |
| 220 | +snprintf(wbuff,kWBUFF_len," Factor= %-15d", sig.LengthBit); |
| 221 | + fwriter->AppendText(wbuff); |
| 222 | + } |
| 223 | + |
| 224 | + fwriter->AppendLine("",2); |
43 | 225 | } |
44 | 226 |
|
45 | 227 | boolCiMainGenerator::SetFinalPath(std::string dirpath) |
@@ -73,3 +255,17 @@ bool CiMainGenerator::SetFinalPath(std::string dirpath) |
73 | 255 |
|
74 | 256 | returntrue; |
75 | 257 | } |
| 258 | + |
| 259 | +voidCiMainGenerator::SetCommonValues(const std::string& drvname) |
| 260 | +{ |
| 261 | + DRVNAME =str_toupper(drvname); |
| 262 | + |
| 263 | +snprintf(wbuff,kWBUFF_len,"%s_USE_BITS_SIGNAL", DRVNAME.c_str()); |
| 264 | + usebits_str = wbuff; |
| 265 | + |
| 266 | +snprintf(wbuff,kWBUFF_len,"%s_USE_DIAG_MONITORS", DRVNAME.c_str()); |
| 267 | + usediag_str = wbuff; |
| 268 | + |
| 269 | +snprintf(wbuff,kWBUFF_len,"%s_USE_CANSTRUCT", DRVNAME.c_str()); |
| 270 | + canframe_str = wbuff; |
| 271 | +} |