EVE 1.0
toc-instance.h
Go to the documentation of this file.
1 #ifndef EVE_TOC_INSTANCE_H_INCLUDED
2 #define EVE_TOC_INSTANCE_H_INCLUDED
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2014-2015, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief TOC table compile-time genarator
36  *
37  * @author DT, Jetro AS
38  */ /******************************************************************/
39 
40 #include <stdint.h>
41 #include <stddef.h>
42 #include <string.h>
43 #include <limits>
44 #include <type_traits>
45 #include <toc/autogen/int2type.h>
50 #include <toc/autogen/flags.h>
51 
52 /**
53  * The utility macro check if a value "test" does not fit into xint16_t representation.
54  * "mmin" and "mmax" are used to distinguish between signed and unsigned values.
55  */
56 #define TOC_LIMIT_OVERFLOWS(mmin, mmax, test) \
57  (((uint32_t)mmin > (uint32_t)mmax) ? \
58  ((int32_t)test > std::numeric_limits<int16_t>::max() || (int32_t)test < std::numeric_limits<int16_t>::min()) : \
59  ((uint32_t)test > std::numeric_limits<uint16_t>::max() || (uint32_t)test < std::numeric_limits<uint16_t>::min()))
60 
61 /**
62  * The utility macro check if one of "mmin" and "mmax" does not fit into xint16_t representation.
63  */
64 #define TOC_NEED_EXTERN_LIMITS(mmin, mmax) \
65  (TOC_LIMIT_OVERFLOWS(mmin, mmax, mmin) || TOC_LIMIT_OVERFLOWS(mmin, mmax, mmax))
66 
67 /* Define standard segments */
68 struct CLoc_SERVICES;
69 struct CLoc_RAM;
70 struct CLoc_COMMAND;
71 struct CLoc_BLE;
72 
73 template <class SegmentLoc>
74 struct CSegment
75 {
76  typedef typename SegmentLoc::segment_t segment_t;
77  static const uint8_t m_segment = SEGMENT_NONE;
78 };
79 
80 /* See toc-app.h for BIND_SEGMENT */
81 BIND_SEGMENT(struct toc_services_t, SERVICES);
82 BIND_SEGMENT(toc_data_t, RAM);
83 BIND_SEGMENT(toc_command_t, COMMAND);
84 
85 /* Location traits */
86 template <class SegmentLoc, class MemberType, MemberType SegmentLoc::segment_t::*member, bool arrayBased>
87 struct CLocationTraits
88 {
89 private:
90  static constexpr size_t raw_size = sizeof(typename std::remove_extent<MemberType>::type);
91  static constexpr size_t raw_count = sizeof(MemberType) / sizeof(typename std::remove_extent<MemberType>::type);
92  static constexpr size_t aligned_size = raw_size;
93 
94 public:
95  static constexpr uint8_t m_segment = SegmentLoc::m_segment;
96  static constexpr size_t m_offset = (uint16_t) (uint32_t) &(((typename SegmentLoc::segment_t*)NULL)->*member);
97  static constexpr size_t m_size = (arrayBased && raw_size == 1) ? raw_count : aligned_size;
98  static constexpr size_t m_count = (arrayBased && raw_size == 1) ? 1 : raw_count;
99 };
100 
101 /*
102  * First step. Find integer constants which cannot be represented as xint16_t
103  * and put them into the unique pool.
104  */
105 #define DECLARE_SEGMENT(...)
106 
107 #define TOC_BEGIN() \
108  DEF_STATIC_COUNTER(ConstId); \
109 
110 /*
111  * The macro declares min and max constants in the unique pool
112  */
113 #define TOC_DECLARE_MIN_MAX(mmin, mmax) \
114  TOC_DECLARE_INT(GET_STATIC_COUNTER(ConstId) * 2 + 0, mmin, TOC_NEED_EXTERN_LIMITS(mmin, mmax)); \
115  TOC_DECLARE_INT(GET_STATIC_COUNTER(ConstId) * 2 + 1, mmax, TOC_NEED_EXTERN_LIMITS(mmin, mmax)); \
116  INC_STATIC_COUNTER(ConstId)
117 
118 /*
119  * TOC interface macro for the first step
120  */
121 #define TOC_INT_PARAM(name, text, uuid, mmin, mmax, loc, ...) \
122 TOC_DECLARE_MIN_MAX(mmin, mmax);
123 
124 #define TOC_BOOL_PARAM(name, text, uuid, loc, ...)
125 
126 #define TOC_STRING_PARAM(name, text, uuid, loc, ...)
127 
128 #define TOC_BINARY_PARAM(name, text, uuid, loc, ...)
129 
130 #define TOC_STRUCT_PARAM(name, text, uuid, pfix, end, loc, ...)
131 
132 #define TOC_SERVICE(name)
133 
134 /*
135  * Output: number of entries and derivates
136  */
137 #define TOC_END() \
138  typedef IntToType<GET_STATIC_COUNTER(ConstId)> CTocTableNumConstEntries; \
139  typedef IntToType<CTocTableNumConstEntries::value * 2 - 1> CTocTableLastConstId; \
140  typedef IntToType<CTocTableLastConstId::value + 1> CTocTableFirstNameId; \
141  typedef typename string_table_t<CTocTableLastConstId>::type CTocTableConstPool;
142 
143 #include EVE_TOC_GEN_H
144 
145 #undef TOC_BEGIN
146 #undef TOC_STRING_PARAM
147 #undef TOC_BINARY_PARAM
148 #undef TOC_INT_PARAM
149 #undef TOC_BOOL_PARAM
150 #undef TOC_STRUCT_PARAM
151 #undef TOC_SERVICE
152 #undef TOC_END
153 
154 /*
155  * Second step. Build traits objects.
156  */
157 
158 #define DECLARE_SEGMENT(...)
159 
160 #define TOC_BEGIN() \
161  DEF_STATIC_COUNTER(VarId);
162 
163 #ifdef TOC_USE_TEXT_UUID
164  #define TOC_LABELS_PER_ENTRY 2
165  #define TOC_STORE_TEXT_AND_CLASS(text, clazz) \
166  TOC_DECLARE_LABEL(GET_STATIC_COUNTER(VarId) * TOC_LABELS_PER_ENTRY + 0, text); \
167  TOC_DECLARE_LABEL(GET_STATIC_COUNTER(VarId) * TOC_LABELS_PER_ENTRY + 1, clazz);
168  #define TOC_TEXT_LABEL_OFFSET(text) \
169  TOC_LABEL_OFFSET(0)
170  #define TOC_UUID_LABEL_OFFSET(uuid) \
171  TOC_LABEL_OFFSET(1)
172 #else /* TOC_USE_TEXT_UUID */
173  #define TOC_LABELS_PER_ENTRY 1
174  #define TOC_STORE_TEXT_AND_CLASS(text, clazz) \
175  TOC_DECLARE_LABEL(GET_STATIC_COUNTER(VarId) * TOC_LABELS_PER_ENTRY + 0, text);
176  #define TOC_TEXT_LABEL_OFFSET(text) \
177  TOC_LABEL_OFFSET(0)
178  #define TOC_UUID_LABEL_OFFSET(uuid) \
179  uuid
180 #endif /* TOC_USE_TEXT_UUID */
181 
182 /*
183  * Instantiates traits for variables.
184  */
185 #define TOC_MAKE_BASE(name, text, uuid, loc, array_based, ...)\
186 struct CVar_ ## loc ## _ ## name; \
187 struct CVarName_ ## name; \
188 struct CLoc_ ## loc; \
189 TOC_DECLARE_NAME(GET_STATIC_COUNTER(VarId) + CTocTableFirstNameId::value, name);\
190 TOC_STORE_TEXT_AND_CLASS(text, uuid) \
191 struct CVar_ ## loc ## _ ## name : public \
192  CExtraTraits < \
193  CVar_ ## loc ## _ ## name, \
194  CFlagsTraits < \
195  CLocationTraits < \
196  CSegment<CLoc_ ## loc>, \
197  decltype(CSegment<CLoc_ ## loc>::segment_t::name), \
198  &CSegment<CLoc_ ## loc>::segment_t::name, \
199  array_based \
200  >, ##__VA_ARGS__ \
201  > \
202  > \
203 { \
204  static const int m_id = GET_STATIC_COUNTER(VarId); \
205 }; \
206 INC_STATIC_COUNTER(VarId)
207 
208 /*
209  * TOC interface macro for the second step
210  */
211 #define TOC_INT_PARAM(name, text, uuid, mmin, mmax, loc, ...) \
212 TOC_MAKE_BASE(name, text, uuid, loc, false, ##__VA_ARGS__);
213 
214 #define TOC_BOOL_PARAM(name, text, uuid, loc, ...) \
215 TOC_MAKE_BASE(name, text, uuid, loc, false, ##__VA_ARGS__);
216 
217 #define TOC_STRING_PARAM(name, text, uuid, loc, ...) \
218 TOC_MAKE_BASE(name, text, uuid, loc, true, ##__VA_ARGS__);
219 
220 #define TOC_BINARY_PARAM(name, text, uuid, loc, ...) \
221 TOC_MAKE_BASE(name, text, uuid, loc, true, ##__VA_ARGS__);
222 
223 #define TOC_STRUCT_PARAM(name, text, uuid, pfix, end, loc, ...) \
224 TOC_MAKE_BASE(name, text, uuid, loc, false, ##__VA_ARGS__); \
225 struct CVar_ ## pfix ## _ ## end; \
226 struct CLoc_ ## pfix \
227 { \
228  typedef typename std::remove_extent< \
229  decltype(CSegment<CLoc_ ## loc>::segment_t::name) \
230  >::type segment_t; \
231 };
232 
233 #define TOC_SERVICE(name) \
234 TOC_MAKE_BASE(name, "", 0, SERVICES, false, __);
235 
236 // Toc table target
237 
238 template <class T>
239 struct CTocTable
240  : public CTocTable<IntToType<T::value - 1> >
241 {};
242 
243 template <>
244 struct CTocTable<IntToType<0> >
245 {};
246 
247 /*
248  * Output: number of entries and derivates
249  */
250 #define TOC_END() \
251  typedef IntToType<__LINE__> CTocTableEndLine; \
252  typedef IntToType<GET_STATIC_COUNTER(VarId)> CTocTableNumEntries; \
253  typedef IntToType<CTocTableNumEntries::value * TOC_LABELS_PER_ENTRY - 1> CTocTableLastLabelId; \
254  typedef IntToType<CTocTableLastConstId::value + CTocTableNumEntries::value> CTocTableLastUniqueId; \
255  typedef IntToType<CTocTableNumEntries::value - 1> CBleIdTableLastId; \
256  typedef CTocTable<CTocTableEndLine> CTocTableFinal; \
257  typedef CStringPool<CTocTableLastUniqueId> CStringPoolFinal; \
258  typedef CLabelPool<CTocTableLastLabelId> CLabelPoolFinal; \
259  typedef CBleIdTranslateTable<CBleIdTableLastId> CBleIdTranslateTableFinal; \
260  typedef typename string_table_t<CTocTableLastUniqueId>::type CStringPoolImpl;
261 
262 #include EVE_TOC_GEN_H
263 
264 #undef TOC_BEGIN
265 #undef TOC_STRING_PARAM
266 #undef TOC_BINARY_PARAM
267 #undef TOC_INT_PARAM
268 #undef TOC_BOOL_PARAM
269 #undef TOC_STRUCT_PARAM
270 #undef TOC_SERVICE
271 #undef TOC_END
272 
273 template<
274  uint8_t type, uint16_t flags, uint16_t name,
275  size_t offset, size_t segment, size_t size, size_t count,
276  int32_t mmin, int32_t mmax,
277  uint16_t label, uint16_t uuid>
278 struct CTocTableEntry
279 {
280 #pragma GCC diagnostic push
281 #pragma GCC diagnostic ignored "-Wnarrowing"
282  constexpr CTocTableEntry()
283  : toc({
284  .Type = type,
285  .Name = name,
286  .Flags = flags | (TOC_NEED_EXTERN_LIMITS(mmin, mmax) ? TOC_FLAG_EXTERN_LIMITS : 0),
287  .Offset = offset,
288  .Segment = segment,
289  .Size = size,
290  .Count = count,
291  .Min = TOC_NEED_EXTERN_LIMITS(mmin, mmax) ? (CStringPoolImpl::getOffset(IntToType<mmin>())) : mmin,
292  .Max = TOC_NEED_EXTERN_LIMITS(mmin, mmax) ? (CStringPoolImpl::getOffset(IntToType<mmax>())) : mmax,
293  .Label = label,
294  .Uuid = uuid,
295  })
296  {}
297 #pragma GCC diagnostic pop
298 
299  static_assert(type < (1 << 4), "TOC: Invalid type");
300  static_assert(name < (1 << 12), "TOC: String pool is too long");
301  static_assert(offset < (1 << 13), "TOC: Segment is too long");
302  static_assert(segment < (1 << 3), "TOC: Invalid segment");
303  static_assert(size < (1 << 8), "TOC: Invalid size");
304  static_assert(count < (1 << 8), "TOC: Invalid count");
305 
306  struct toc_t toc;
307 };
308 
309 // Third step. Build the table
310 
311 #define TOC_BEGIN()
312 
313 #define TOC_NAME_OFFSET(name) \
314  CStringPoolImpl::name ## _t::offset
315 
316 #define TOC_LABEL_OFFSET(id) \
317  (sizeof(CStringPoolFinal) + CLabelTableEntry<IntToType<GET_STATIC_COUNTER(VarId) * TOC_LABELS_PER_ENTRY + (id)> >::offset)
318 
319 #define TOC_STRING_PARAM(name, text, uuid, loc, ...) \
320 TOC_DECLARE_BLE_ID(CVar_ ## loc ## _ ## name); \
321 template <> \
322 struct CTocTable<IntToType<__LINE__> > \
323  : public CTocTable <IntToType<__LINE__ - 1> > \
324 { \
325  const CTocTableEntry< \
326  TOC_VAL_TYPE_STRING, \
327  CVar_ ## loc ## _ ## name::m_flags, \
328  TOC_NAME_OFFSET(name), \
329  CVar_ ## loc ## _ ## name::m_offset, \
330  CVar_ ## loc ## _ ## name::m_segment, \
331  CVar_ ## loc ## _ ## name::m_size, \
332  CVar_ ## loc ## _ ## name::m_count, \
333  0, \
334  0, \
335  TOC_TEXT_LABEL_OFFSET(text), \
336  TOC_UUID_LABEL_OFFSET(uuid) \
337  > tocTableEntry; \
338 };
339 
340 #define TOC_BINARY_PARAM(name, text, uuid, loc, ...) \
341 TOC_DECLARE_BLE_ID(CVar_ ## loc ## _ ## name); \
342 template <> \
343 struct CTocTable<IntToType<__LINE__> > \
344  : public CTocTable <IntToType<__LINE__ - 1> > \
345 { \
346  const CTocTableEntry< \
347  TOC_VAL_TYPE_STRING, \
348  CVar_ ## loc ## _ ## name::m_flags \
349  | TOC_FLAG_BINARY, \
350  TOC_NAME_OFFSET(name), \
351  CVar_ ## loc ## _ ## name::m_offset, \
352  CVar_ ## loc ## _ ## name::m_segment, \
353  CVar_ ## loc ## _ ## name::m_size, \
354  CVar_ ## loc ## _ ## name::m_count, \
355  0, \
356  0, \
357  TOC_TEXT_LABEL_OFFSET(text), \
358  TOC_UUID_LABEL_OFFSET(uuid) \
359  > tocTableEntry; \
360 };
361 
362 #define TOC_INT_PARAM(name, text, uuid, mmin, mmax, loc, ...) \
363 TOC_DECLARE_BLE_ID(CVar_ ## loc ## _ ## name); \
364 template <> \
365 struct CTocTable<IntToType<__LINE__> > \
366  : public CTocTable <IntToType<__LINE__ - 1> > \
367 { \
368  const CTocTableEntry< \
369  TOC_VAL_TYPE_INT, \
370  CVar_ ## loc ## _ ## name::m_flags, \
371  TOC_NAME_OFFSET(name), \
372  CVar_ ## loc ## _ ## name::m_offset, \
373  CVar_ ## loc ## _ ## name::m_segment, \
374  CVar_ ## loc ## _ ## name::m_size, \
375  CVar_ ## loc ## _ ## name::m_count, \
376  mmin, \
377  mmax, \
378  TOC_TEXT_LABEL_OFFSET(text), \
379  TOC_UUID_LABEL_OFFSET(uuid) \
380  > tocTableEntry; \
381 };
382 
383 #define TOC_BOOL_PARAM(name, text, uuid, loc, ...) \
384 TOC_DECLARE_BLE_ID(CVar_ ## loc ## _ ## name); \
385 template <> \
386 struct CTocTable<IntToType<__LINE__> > \
387  : public CTocTable <IntToType<__LINE__ - 1> > \
388 { \
389  const CTocTableEntry< \
390  TOC_VAL_TYPE_BOOL, \
391  CVar_ ## loc ## _ ## name::m_flags, \
392  TOC_NAME_OFFSET(name), \
393  CVar_ ## loc ## _ ## name::m_offset, \
394  CVar_ ## loc ## _ ## name::m_segment, \
395  CVar_ ## loc ## _ ## name::m_size, \
396  CVar_ ## loc ## _ ## name::m_count, \
397  0, \
398  1, \
399  TOC_TEXT_LABEL_OFFSET(text), \
400  TOC_UUID_LABEL_OFFSET(uuid) \
401  > tocTableEntry; \
402 };
403 
404 #define TOC_STRUCT_PARAM(name, text, uuid, pfix, end, loc, ...) \
405 TOC_DECLARE_BLE_ID(CVar_ ## loc ## _ ## name); \
406 template <> \
407 struct CTocTable<IntToType<__LINE__> > \
408  : public CTocTable <IntToType<__LINE__ - 1> > \
409 { \
410  const CTocTableEntry< \
411  TOC_VAL_TYPE_STRUCT, \
412  CVar_ ## loc ## _ ## name::m_flags, \
413  TOC_NAME_OFFSET(name), \
414  CVar_ ## loc ## _ ## name::m_offset, \
415  CVar_ ## loc ## _ ## name::m_segment, \
416  CVar_ ## loc ## _ ## name::m_size, \
417  CVar_ ## loc ## _ ## name::m_count, \
418  0, \
419  CVar_ ## end::m_id - CVar_ ## loc ## _ ## name::m_id, \
420  TOC_TEXT_LABEL_OFFSET(text), \
421  TOC_UUID_LABEL_OFFSET(uuid) \
422  > tocTableEntry; \
423 };
424 
425 #define TOC_SERVICE(name) \
426 TOC_DECLARE_BLE_ID(CVar_SERVICES_ ## name); \
427 template <> \
428 struct CTocTable<IntToType<__LINE__> > \
429  : public CTocTable <IntToType<__LINE__ - 1> > \
430 { \
431  const CTocTableEntry< \
432  TOC_VAL_TYPE_SERVICE, \
433  0, \
434  TOC_NAME_OFFSET(name), \
435  CVar_SERVICES_ ## name::m_offset, \
436  CVar_SERVICES_ ## name::m_segment, \
437  CVar_SERVICES_ ## name::m_size, \
438  CVar_SERVICES_ ## name::m_count, \
439  0, \
440  0, \
441  TOC_TEXT_LABEL_OFFSET(""), \
442  TOC_UUID_LABEL_OFFSET(0) \
443  > tocTableEntry; \
444 };
445 
446 #define TOC_END()
447 
448 #include EVE_TOC_GEN_H
449 
450 #undef TOC_BEGIN
451 #undef TOC_STRING_PARAM
452 #undef TOC_BINARY_PARAM
453 #undef TOC_INT_PARAM
454 #undef TOC_BOOL_PARAM
455 #undef TOC_STRUCT_PARAM
456 #undef TOC_SERVICE
457 #undef TOC_END
458 
459 #ifdef INSTATIATE_TOC_RECORDS
460 extern "C" void INSTATIATE_TOC_RECORDS(struct toc_blob_t *Ptr);
461 void INSTATIATE_TOC_RECORDS(struct toc_blob_t *Ptr)
462 {
463  static constexpr CTocTableFinal TocTable;
464  static constexpr CBleIdTranslateTableFinal BleIdTranslateTable;
465  static constexpr struct {
466  CStringPoolFinal poolStrings;
467  CLabelPoolFinal poolLabels;
468  } TocStringPool;
469  Ptr->Toc = (toc_t *) &TocTable;
470  Ptr->StringPool = (const char *) &TocStringPool;
471  Ptr->Count = sizeof(TocTable) / sizeof(toc_t);
472 #if 0
473  if (CBleIdTranslateTableFinal::empty) {
474  Ptr->BleIdTable = NULL;
475  Ptr->BleIdCount = 0;
476  } else {
477  Ptr->BleIdTable = (const uint8_t *) &BleIdTranslateTable;
478  Ptr->BleIdCount = sizeof(BleIdTranslateTable);
479  }
480 #endif
481 }
482 #endif /* INSTATIATE_TOC_RECORDS */
483 
484 #endif /* EVE_TOC_INSTANCE_H_INCLUDED */
A part of TOC table compile-time generator.
Applikasjon-spesifikk parameter beskrivelse.
Definition: toc-app.h:144
#define BIND_SEGMENT(type, tag)
The utility macro binds a segment structure "type" with tag "tag". See toc-instance.h for defails.
Definition: toc-app.h:86
uint8_t Count
Definition: types.h:68
A part of TOC table compile-time generator.
#define TOC_NEED_EXTERN_LIMITS(mmin, mmax)
Definition: toc-instance.h:64
#define TOC_FLAG_EXTERN_LIMITS
Definition: toc-app.h:128
A part of TOC table compile-time generator.
const char * StringPool
Definition: types.h:67
A part of TOC table compile-time generator.
A part of TOC table compile-time generator.
const struct toc_t * Toc
Definition: types.h:66
A part of TOC table compile-time generator.