barectf: reflow licence headers for 72 columns
[barectf.git] / barectf / templates.py
1 # The MIT License (MIT)
2 #
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 _CLOCK_CB = '{return_ctype} (*{cname}_clock_get_value)(void *);'
25
26
27 _PLATFORM_CALLBACKS_BEGIN = '''/* barectf platform callbacks */
28 struct {prefix}platform_callbacks {{
29 /* clock callbacks */'''
30
31
32 _PLATFORM_CALLBACKS_END = '''
33 /* is back-end full? */
34 int (*is_backend_full)(void *);
35
36 /* open packet */
37 void (*open_packet)(void *);
38
39 /* close packet */
40 void (*close_packet)(void *);
41 };'''
42
43
44 _CTX_PARENT = '''/* common barectf context */
45 struct {prefix}ctx {{
46 /* platform callbacks */
47 struct {prefix}platform_callbacks cbs;
48
49 /* platform data (passed to callbacks) */
50 void *data;
51
52 /* output buffer (will contain a CTF binary packet) */
53 uint8_t *buf;
54
55 /* packet size in bits */
56 uint32_t packet_size;
57
58 /* content size in bits */
59 uint32_t content_size;
60
61 /* current position from beginning of packet in bits */
62 uint32_t at;
63
64 /* packet header + context size (content offset) */
65 uint32_t off_content;
66
67 /* events discarded */
68 uint32_t events_discarded;
69
70 /* current packet is opened */
71 int packet_is_open;
72
73 /* in tracing code */
74 volatile int in_tracing_section;
75
76 /* tracing is enabled */
77 volatile int is_tracing_enabled;
78
79 /* use current/last event timestamp when opening/closing packets */
80 int use_cur_last_event_ts;
81 }};'''
82
83
84 _CTX_BEGIN = '''/* context for stream `{sname}` */
85 struct {prefix}{sname}_ctx {{
86 /* parent */
87 struct {prefix}ctx parent;
88
89 /* config-specific members follow */'''
90
91
92 _CTX_END = '};'
93
94
95 _FUNC_INIT_PROTO = '''/* initialize context */
96 void {prefix}init(
97 void *vctx,
98 uint8_t *buf,
99 uint32_t buf_size,
100 struct {prefix}platform_callbacks cbs,
101 void *data
102 )'''
103
104
105 _FUNC_INIT_BODY = '''{{
106 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
107 ctx->cbs = cbs;
108 ctx->data = data;
109 ctx->buf = buf;
110 ctx->packet_size = _BYTES_TO_BITS(buf_size);
111 ctx->at = 0;
112 ctx->events_discarded = 0;
113 ctx->packet_is_open = 0;
114 ctx->in_tracing_section = 0;
115 ctx->is_tracing_enabled = 1;
116 ctx->use_cur_last_event_ts = 0;
117 }}'''
118
119
120 _FUNC_OPEN_PROTO_BEGIN = '''/* open packet for stream `{sname}` */
121 void {prefix}{sname}_open_packet(
122 struct {prefix}{sname}_ctx *ctx'''
123
124
125 _FUNC_OPEN_PROTO_END = ')'
126
127
128 _FUNC_OPEN_BODY_BEGIN = '''{{
129 {ts}
130 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
131
132 /*
133 * This function is either called by a tracing function, or
134 * directly by the platform.
135 *
136 * If it's called by a tracing function, then
137 * ctx->parent.in_tracing_section is 1, so it's safe to open
138 * the packet here (alter the packet), even if tracing was
139 * disabled in the meantime because we're already in a tracing
140 * section (which finishes at the end of the tracing function
141 * call).
142 *
143 * If it's called directly by the platform, then if tracing is
144 * disabled, we don't want to alter the packet, and return
145 * immediately.
146 */
147 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
148 ctx->parent.in_tracing_section = 0;
149 return;
150 }}
151
152 /* we can modify the packet */
153 ctx->parent.in_tracing_section = 1;
154 '''
155
156
157 _FUNC_OPEN_BODY_END = '''
158 /* save content beginning's offset */
159 ctx->parent.off_content = ctx->parent.at;
160
161 /* mark current packet as open */
162 ctx->parent.packet_is_open = 1;
163
164 /* not tracing anymore */
165 ctx->parent.in_tracing_section = saved_in_tracing_section;
166 }'''
167
168
169 _FUNC_CLOSE_PROTO = '''/* close packet for stream `{sname}` */
170 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
171
172
173 _FUNC_CLOSE_BODY_BEGIN = '''{{
174 {ts}
175 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
176
177 /*
178 * This function is either called by a tracing function, or
179 * directly by the platform.
180 *
181 * If it's called by a tracing function, then
182 * ctx->parent.in_tracing_section is 1, so it's safe to close
183 * the packet here (alter the packet), even if tracing was
184 * disabled in the meantime, because we're already in a tracing
185 * section (which finishes at the end of the tracing function
186 * call).
187 *
188 * If it's called directly by the platform, then if tracing is
189 * disabled, we don't want to alter the packet, and return
190 * immediately.
191 */
192 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
193 ctx->parent.in_tracing_section = 0;
194 return;
195 }}
196
197 /* we can modify the packet */
198 ctx->parent.in_tracing_section = 1;
199 '''
200
201
202 _FUNC_CLOSE_BODY_END = '''
203 /* go back to end of packet */
204 ctx->parent.at = ctx->parent.packet_size;
205
206 /* mark packet as closed */
207 ctx->parent.packet_is_open = 0;
208
209 /* not tracing anymore */
210 ctx->parent.in_tracing_section = saved_in_tracing_section;
211 }'''
212
213
214 _DEFINE_DEFAULT_STREAM_TRACE = '#define {prefix}trace_{evname} {prefix}{sname}_trace_{evname}'
215
216
217 _FUNC_TRACE_PROTO_BEGIN = '''/* trace (stream `{sname}`, event `{evname}`) */
218 void {prefix}{sname}_trace_{evname}(
219 struct {prefix}{sname}_ctx *ctx'''
220
221
222 _FUNC_TRACE_PROTO_END = ')'
223
224
225 _FUNC_TRACE_BODY = '''{{
226 uint32_t ev_size;
227
228 /* save timestamp */
229 {save_ts}
230
231 if (!ctx->parent.is_tracing_enabled) {{
232 return;
233 }}
234
235 /* we can modify the packet */
236 ctx->parent.in_tracing_section = 1;
237
238 /* get event size */
239 ev_size = _get_event_size_{sname}_{evname}(TO_VOID_PTR(ctx){params});
240
241 /* do we have enough space to serialize? */
242 if (!_reserve_event_space(TO_VOID_PTR(ctx), ev_size)) {{
243 /* no: forget this */
244 ctx->parent.in_tracing_section = 0;
245 return;
246 }}
247
248 /* serialize event */
249 _serialize_event_{sname}_{evname}(TO_VOID_PTR(ctx){params});
250
251 /* commit event */
252 _commit_event(TO_VOID_PTR(ctx));
253
254 /* not tracing anymore */
255 ctx->parent.in_tracing_section = 0;
256 }}'''
257
258
259 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN = '''static uint32_t _get_event_size_{sname}_{evname}(
260 void *vctx'''
261
262
263 _FUNC_GET_EVENT_SIZE_PROTO_END = ')'
264
265
266 _FUNC_GET_EVENT_SIZE_BODY_BEGIN = '''{{
267 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
268 uint32_t at = ctx->at;'''
269
270
271 _FUNC_GET_EVENT_SIZE_BODY_END = ''' return at - ctx->at;
272 }'''
273
274
275 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN = '''static void _serialize_stream_event_header_{sname}(
276 void *vctx,
277 uint32_t event_id'''
278
279
280 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END = ')'
281
282
283 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN = '''{{
284 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
285
286
287 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END = '}'
288
289
290 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN = '''static void _serialize_stream_event_context_{sname}(
291 void *vctx'''
292
293
294 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END = ')'
295
296
297 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN = '''{{
298 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
299
300
301 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END = '}'
302
303
304 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN = '''static void _serialize_event_{sname}_{evname}(
305 void *vctx'''
306
307
308 _FUNC_SERIALIZE_EVENT_PROTO_END = ')'
309
310
311 _FUNC_SERIALIZE_EVENT_BODY_BEGIN = '''{{
312 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
313
314
315 _FUNC_SERIALIZE_EVENT_BODY_END = '}'
316
317
318 _HEADER_BEGIN = '''#ifndef _{ucprefix}H
319 #define _{ucprefix}H
320
321 /*
322 * The MIT License (MIT)
323 *
324 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
325 *
326 * Permission is hereby granted, free of charge, to any person obtaining
327 * a copy of this software and associated documentation files (the
328 * "Software"), to deal in the Software without restriction, including
329 * without limitation the rights to use, copy, modify, merge, publish,
330 * distribute, sublicense, and/or sell copies of the Software, and to
331 * permit persons to whom the Software is furnished to do so, subject to
332 * the following conditions:
333 *
334 * The above copyright notice and this permission notice shall be
335 * included in all copies or substantial portions of the Software.
336 *
337 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
338 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
339 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
340 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
341 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
342 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
343 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
344 * SOFTWARE.
345 *
346 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
347 *
348 * The following C code was generated by barectf {version}
349 * on {date}.
350 *
351 * For more details, see <http://barectf.org>.
352 */
353
354 #include <stdint.h>
355
356 #include "{bitfield_header_filename}"
357
358 #ifdef __cplusplus
359 extern "C" {{
360 #endif
361
362 {prefix_def}
363 {default_stream_def}
364
365 {default_stream_trace_defs}
366
367 struct {prefix}ctx;
368
369 uint32_t {prefix}packet_size(void *ctx);
370 int {prefix}packet_is_full(void *ctx);
371 int {prefix}packet_is_empty(void *ctx);
372 uint32_t {prefix}packet_events_discarded(void *ctx);
373 uint8_t *{prefix}packet_buf(void *ctx);
374 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
375 uint32_t {prefix}packet_buf_size(void *ctx);
376 int {prefix}packet_is_open(void *ctx);
377 int {prefix}is_in_tracing_section(void *ctx);
378 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx);
379 int {prefix}is_tracing_enabled(void *ctx);
380 void {prefix}enable_tracing(void *ctx, int enable);'''
381
382
383 _HEADER_END = '''#ifdef __cplusplus
384 }}
385 #endif
386
387 #endif /* _{ucprefix}H */
388 '''
389
390
391 _C_SRC = '''/*
392 * The MIT License (MIT)
393 *
394 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
395 *
396 * Permission is hereby granted, free of charge, to any person obtaining
397 * a copy of this software and associated documentation files (the
398 * "Software"), to deal in the Software without restriction, including
399 * without limitation the rights to use, copy, modify, merge, publish,
400 * distribute, sublicense, and/or sell copies of the Software, and to
401 * permit persons to whom the Software is furnished to do so, subject to
402 * the following conditions:
403 *
404 * The above copyright notice and this permission notice shall be
405 * included in all copies or substantial portions of the Software.
406 *
407 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
408 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
409 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
410 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
411 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
412 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
413 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
414 * SOFTWARE.
415 *
416 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
417 *
418 * The following C code was generated by barectf {version}
419 * on {date}.
420 *
421 * For more details, see <http://barectf.org>.
422 */
423
424 #include <stdint.h>
425 #include <string.h>
426 #include <assert.h>
427
428 #include "{header_filename}"
429
430 #define _ALIGN(_at, _align) \\
431 do {{ \\
432 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
433 }} while (0)
434
435 #ifdef __cplusplus
436 # define TO_VOID_PTR(_value) static_cast<void *>(_value)
437 # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
438 #else
439 # define TO_VOID_PTR(_value) ((void *) (_value))
440 # define FROM_VOID_PTR(_type, _value) ((_type *) (_value))
441 #endif
442
443 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
444 #define _BYTES_TO_BITS(_x) ((_x) << 3)
445
446 union f2u {{
447 float f;
448 uint32_t u;
449 }};
450
451 union d2u {{
452 double f;
453 uint64_t u;
454 }};
455
456 uint32_t {prefix}packet_size(void *ctx)
457 {{
458 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_size;
459 }}
460
461 int {prefix}packet_is_full(void *ctx)
462 {{
463 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
464
465 return cctx->at == cctx->packet_size;
466 }}
467
468 int {prefix}packet_is_empty(void *ctx)
469 {{
470 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
471
472 return cctx->at <= cctx->off_content;
473 }}
474
475 uint32_t {prefix}packet_events_discarded(void *ctx)
476 {{
477 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->events_discarded;
478 }}
479
480 uint8_t *{prefix}packet_buf(void *ctx)
481 {{
482 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->buf;
483 }}
484
485 uint32_t {prefix}packet_buf_size(void *ctx)
486 {{
487 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
488
489 return _BITS_TO_BYTES(cctx->packet_size);
490 }}
491
492 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
493 {{
494 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
495
496 cctx->buf = buf;
497 cctx->packet_size = _BYTES_TO_BITS(buf_size);
498 }}
499
500 int {prefix}packet_is_open(void *ctx)
501 {{
502 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_is_open;
503 }}
504
505 int {prefix}is_in_tracing_section(void *ctx)
506 {{
507 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
508 }}
509
510 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx)
511 {{
512 return &FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
513 }}
514
515 int {prefix}is_tracing_enabled(void *ctx)
516 {{
517 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled;
518 }}
519
520 void {prefix}enable_tracing(void *ctx, int enable)
521 {{
522 FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled = enable;
523 }}
524
525 static
526 void _write_cstring(struct {prefix}ctx *ctx, const char *src)
527 {{
528 uint32_t sz = strlen(src) + 1;
529
530 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
531 ctx->at += _BYTES_TO_BITS(sz);
532 }}
533
534 static
535 int _reserve_event_space(void *vctx, uint32_t ev_size)
536 {{
537 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
538
539 /* event _cannot_ fit? */
540 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
541 ctx->events_discarded++;
542
543 return 0;
544 }}
545
546 /* packet is full? */
547 if ({prefix}packet_is_full(ctx)) {{
548 /* yes: is back-end full? */
549 if (ctx->cbs.is_backend_full(ctx->data)) {{
550 /* yes: discard event */
551 ctx->events_discarded++;
552
553 return 0;
554 }}
555
556 /* back-end is not full: open new packet */
557 ctx->use_cur_last_event_ts = 1;
558 ctx->cbs.open_packet(ctx->data);
559 ctx->use_cur_last_event_ts = 0;
560 }}
561
562 /* event fits the current packet? */
563 if (ev_size > (ctx->packet_size - ctx->at)) {{
564 /* no: close packet now */
565 ctx->use_cur_last_event_ts = 1;
566 ctx->cbs.close_packet(ctx->data);
567 ctx->use_cur_last_event_ts = 0;
568
569 /* is back-end full? */
570 if (ctx->cbs.is_backend_full(ctx->data)) {{
571 /* yes: discard event */
572 ctx->events_discarded++;
573
574 return 0;
575 }}
576
577 /* back-end is not full: open new packet */
578 ctx->use_cur_last_event_ts = 1;
579 ctx->cbs.open_packet(ctx->data);
580 ctx->use_cur_last_event_ts = 0;
581 assert(ev_size <= (ctx->packet_size - ctx->at));
582 }}
583
584 return 1;
585 }}
586
587 static
588 void _commit_event(void *vctx)
589 {{
590 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
591
592 /* is packet full? */
593 if ({prefix}packet_is_full(ctx)) {{
594 /* yes: close it now */
595 ctx->cbs.close_packet(ctx->data);
596 }}
597 }}'''
598
599
600 _BITFIELD = '''#ifndef _$PREFIX$BITFIELD_H
601 #define _$PREFIX$BITFIELD_H
602
603 /*
604 * BabelTrace
605 *
606 * Bitfields read/write functions.
607 *
608 * Copyright (c) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
609 *
610 * Permission is hereby granted, free of charge, to any person obtaining
611 * a copy of this software and associated documentation files (the
612 * "Software"), to deal in the Software without restriction, including
613 * without limitation the rights to use, copy, modify, merge, publish,
614 * distribute, sublicense, and/or sell copies of the Software, and to
615 * permit persons to whom the Software is furnished to do so, subject to
616 * the following conditions:
617 *
618 * The above copyright notice and this permission notice shall be
619 * included in all copies or substantial portions of the Software.
620 *
621 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
622 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
623 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
624 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
625 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
626 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
627 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
628 * SOFTWARE.
629 */
630
631 #include <limits.h>
632
633 #ifdef __cplusplus
634 # define CAST_PTR(_type, _value) \\
635 static_cast<_type>(static_cast<void *>(_value))
636 #else
637 # define CAST_PTR(_type, _value) ((void *) (_value))
638 #endif
639
640 #define $PREFIX$BYTE_ORDER $ENDIAN_DEF$
641
642 /* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
643 #define _$prefix$bt_piecewise_rshift(_vtype, _v, _shift) \\
644 do { \\
645 unsigned long ___shift = (_shift); \\
646 unsigned long sb = (___shift) / (sizeof(_v) * CHAR_BIT - 1); \\
647 unsigned long final = (___shift) % (sizeof(_v) * CHAR_BIT - 1); \\
648 \\
649 for (; sb; sb--) \\
650 _v >>= sizeof(_v) * CHAR_BIT - 1; \\
651 _v >>= final; \\
652 } while (0)
653
654 /*
655 * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness
656 *
657 * Save integer to the bitfield, which starts at the "start" bit, has "len"
658 * bits.
659 * The inside of a bitfield is from high bits to low bits.
660 * Uses native endianness.
661 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
662 * For signed "v", sign-extend v if bitfield is larger than v.
663 *
664 * On little endian, bytes are placed from the less significant to the most
665 * significant. Also, consecutive bitfields are placed from lower bits to higher
666 * bits.
667 *
668 * On big endian, bytes are places from most significant to less significant.
669 * Also, consecutive bitfields are placed from higher to lower bits.
670 */
671
672 #define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \\
673 do { \\
674 _vtype __v = (_v); \\
675 type *__ptr = CAST_PTR(type *, _ptr); \\
676 unsigned long __start = (_start), __length = (_length); \\
677 type mask, cmask; \\
678 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
679 unsigned long start_unit, end_unit, this_unit; \\
680 unsigned long end, cshift; /* cshift is "complement shift" */ \\
681 \\
682 if (!__length) \\
683 break; \\
684 \\
685 end = __start + __length; \\
686 start_unit = __start / ts; \\
687 end_unit = (end + (ts - 1)) / ts; \\
688 \\
689 /* Trim v high bits */ \\
690 if (__length < sizeof(__v) * CHAR_BIT) \\
691 __v &= ~((~(_vtype) 0) << __length); \\
692 \\
693 /* We can now append v with a simple "or", shift it piece-wise */ \\
694 this_unit = start_unit; \\
695 if (start_unit == end_unit - 1) { \\
696 mask = ~((~(type) 0) << (__start % ts)); \\
697 if (end % ts) \\
698 mask |= (~(type) 0) << (end % ts); \\
699 cmask = (type) __v << (__start % ts); \\
700 cmask &= ~mask; \\
701 __ptr[this_unit] &= mask; \\
702 __ptr[this_unit] |= cmask; \\
703 break; \\
704 } \\
705 if (__start % ts) { \\
706 cshift = __start % ts; \\
707 mask = ~((~(type) 0) << cshift); \\
708 cmask = (type) __v << cshift; \\
709 cmask &= ~mask; \\
710 __ptr[this_unit] &= mask; \\
711 __ptr[this_unit] |= cmask; \\
712 _$prefix$bt_piecewise_rshift(_vtype, __v, ts - cshift); \\
713 __start += ts - cshift; \\
714 this_unit++; \\
715 } \\
716 for (; this_unit < end_unit - 1; this_unit++) { \\
717 __ptr[this_unit] = (type) __v; \\
718 _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\
719 __start += ts; \\
720 } \\
721 if (end % ts) { \\
722 mask = (~(type) 0) << (end % ts); \\
723 cmask = (type) __v; \\
724 cmask &= ~mask; \\
725 __ptr[this_unit] &= mask; \\
726 __ptr[this_unit] |= cmask; \\
727 } else \\
728 __ptr[this_unit] = (type) __v; \\
729 } while (0)
730
731 #define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \\
732 do { \\
733 _vtype __v = (_v); \\
734 type *__ptr = CAST_PTR(type *, _ptr); \\
735 unsigned long __start = (_start), __length = (_length); \\
736 type mask, cmask; \\
737 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
738 unsigned long start_unit, end_unit, this_unit; \\
739 unsigned long end, cshift; /* cshift is "complement shift" */ \\
740 \\
741 if (!__length) \\
742 break; \\
743 \\
744 end = __start + __length; \\
745 start_unit = __start / ts; \\
746 end_unit = (end + (ts - 1)) / ts; \\
747 \\
748 /* Trim v high bits */ \\
749 if (__length < sizeof(__v) * CHAR_BIT) \\
750 __v &= ~((~(_vtype) 0) << __length); \\
751 \\
752 /* We can now append v with a simple "or", shift it piece-wise */ \\
753 this_unit = end_unit - 1; \\
754 if (start_unit == end_unit - 1) { \\
755 mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \\
756 if (__start % ts) \\
757 mask |= (~((type) 0)) << (ts - (__start % ts)); \\
758 cmask = (type) __v << ((ts - (end % ts)) % ts); \\
759 cmask &= ~mask; \\
760 __ptr[this_unit] &= mask; \\
761 __ptr[this_unit] |= cmask; \\
762 break; \\
763 } \\
764 if (end % ts) { \\
765 cshift = end % ts; \\
766 mask = ~((~(type) 0) << (ts - cshift)); \\
767 cmask = (type) __v << (ts - cshift); \\
768 cmask &= ~mask; \\
769 __ptr[this_unit] &= mask; \\
770 __ptr[this_unit] |= cmask; \\
771 _$prefix$bt_piecewise_rshift(_vtype, __v, cshift); \\
772 end -= cshift; \\
773 this_unit--; \\
774 } \\
775 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \\
776 __ptr[this_unit] = (type) __v; \\
777 _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\
778 end -= ts; \\
779 } \\
780 if (__start % ts) { \\
781 mask = (~(type) 0) << (ts - (__start % ts)); \\
782 cmask = (type) __v; \\
783 cmask &= ~mask; \\
784 __ptr[this_unit] &= mask; \\
785 __ptr[this_unit] |= cmask; \\
786 } else \\
787 __ptr[this_unit] = (type) __v; \\
788 } while (0)
789
790 /*
791 * $prefix$bt_bitfield_write_le - write integer to a bitfield in little endian
792 * $prefix$bt_bitfield_write_be - write integer to a bitfield in big endian
793 */
794
795 #if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN)
796
797 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\
798 _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v)
799
800 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\
801 _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _vtype, _v)
802
803 #elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN)
804
805 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\
806 _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _vtype, _v)
807
808 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\
809 _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v)
810
811 #else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */
812
813 #error "Byte order not supported"
814
815 #endif
816
817 #endif /* _$PREFIX$BITFIELD_H */
818 '''
This page took 0.05581 seconds and 4 git commands to generate.