P99
p99_init.h
Go to the documentation of this file.
1 /* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2 /* */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the author and copyright holder for this work is */
5 /* (C) copyright 2013-2014 Jens Gustedt, INRIA, France */
6 /* */
7 /* This file is free software; it is part of the P99 project. */
8 /* */
9 /* Licensed under the Apache License, Version 2.0 (the "License"); */
10 /* you may not use this file except in compliance with the License. */
11 /* You may obtain a copy of the License at */
12 /* */
13 /* http://www.apache.org/licenses/LICENSE-2.0 */
14 /* */
15 /* Unless required by applicable law or agreed to in writing, software */
16 /* distributed under the License is distributed on an "AS IS" BASIS, */
17 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
18 /* See the License for the specific language governing permissions and */
19 /* limitations under the License. */
20 /* */
21 #ifndef P99_INIT_H_
22 # define P99_INIT_H_
23 
24 # include "p99_if.h"
25 # include "p99_callback.h"
26 # include "p99_hook.h"
27 
49 # define P00_INIT_1
50 # define P00_INIT_2
51 # define P00_INIT_3
52 
53 # define P00_INIT_NR P99_PASTE3(P00_INIT_3, P00_INIT_2, P00_INIT_1)
54 
55 # define P00_INIT_FUNCTION(NR) P99_IF_EMPTY(NR)(P99_PASTE2(p00_init_function_, P00_INIT_NR))(P99_PASTE2(p00_init_function_, NR))
56 
57 # define P00_HAVE_INIT_FUNCTION(NR) P99_IF_EMPTY(NR)(P99_PASTE2(p00_have_init_function_, P00_INIT_NR))(P99_PASTE2(p00_have_init_function_, NR))
58 
59 # define P00_INIT_FUNC_VAR_S(_0, _1, I) \
60 P99_TENTATIVE_DEC(bool const, P00_HAVE_INIT_FUNCTION(I)); \
61 P99_TENTATIVE_DEC(p99_callback_el const, P00_INIT_FUNCTION(I))
62 
63 P99_FOR(, P99_MAX_NUMBER, P00_SEP, P00_INIT_FUNC_VAR_S, P99_REP(P99_MAX_NUMBER,));
64 
65 # define P00_INIT_TRIGGER_FUNCTION_1(_0, _1, I) \
66 do { \
67  if (P00_HAVE_INIT_FUNCTION(I)) p99_callback_el_call(P00_INIT_FUNCTION(I)); \
68  } while (false)
69 
70 # define P00_INIT_FUNCTION_(NAME, NR) \
71 void NAME(void); \
72 P99_TENTATIVE_DEF(bool const, P00_HAVE_INIT_FUNCTION(NR)) = true; \
73 P99_TENTATIVE_DEF(p99_callback_el const, P00_INIT_FUNCTION(NR)) = { .p00_void = { .p00_void_func = NAME, }, }
74 
75 # ifdef P00_DOXYGEN
76 
143 # define P99_INIT_FUNCTION_DECLARE(FUNC, NR)
144 # else
145 # define P99_INIT_FUNCTION_DECLARE(...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 2)(P00_INIT_FUNCTION_(__VA_ARGS__))(P00_INIT_FUNCTION_(__VA_ARGS__,))
146 # endif
147 
148 # define P00_INIT_VARIABLE(NAME, FUNC, NR) \
149 P99_TENTATIVE_DEF(p99_callback_el const, P00_INIT_FUNCTION(NR)) \
150 = { \
151  .p00_voidptr_func = (FUNC), \
152  .p00_void = { \
153  .p00_arg = &(NAME), \
154  }, \
155 }
156 
157 # ifdef P00_DOXYGEN
158 
179 # define P99_INIT_VARIABLE(NAME, FUNC, NR)
180 # else
181 # define P99_INIT_VARIABLE(...) P99_IF_EQ(P99_NARG(__VA_ARGS__), 3)(P00_INIT_VARIABLE(__VA_ARGS__))(P00_INIT_VARIABLE(__VA_ARGS__,))
182 # endif
183 
184 # if defined(P00_DOXYGEN)
185 
190 # define P99_INTERCEPT_MAIN
191 # endif
192 
193 # if defined(P99_INTERCEPT_MAIN) || defined(P00_DOXYGEN)
194 
238 # define P99_MAIN_INTERCEPT(NAME) \
239 int NAME(int, char*[]); \
240 P99_WEAK(P99_PASTE2(p00_init_func_, NAME)) \
241  void P99_PASTE2(p00_init_func_, NAME)(int*, char***); \
242 P99_WEAK(main) \
243 int main(int p00_argc, char**p00_argv) { \
244  fprintf(stderr, "%s: intercepting " P99_STRINGIFY(NAME) "\n", __func__); \
245  P99_PASTE2(p00_init_func_, NAME)(&p00_argc, &p00_argv); \
246  return NAME(p00_argc, p00_argv); \
247 } \
248 P99_WEAK(P99_PASTE2(p00_init_func_, NAME)) \
249 void P99_PASTE2(p00_init_func_, NAME)(int * p00_argc, char***p00_argv)
250 
251 # define P99_INIT_TRIGGER(NAME, ARGC, ARGV) P99_NOP
252 
253 # else
254 
255 # define P99_MAIN_INTERCEPT(NAME) \
256 P99_WEAK(P99_PASTE2(p00_init_func_, NAME)) \
257 void P99_PASTE2(p00_init_func_, NAME)(int * p00_argc, char***p00_argv)
258 
259 # define P99_INIT_TRIGGER(NAME, ARGC, ARGV) P99_PASTE2(p00_init_func_, NAME)((ARGC), (ARGV))
260 
261 # endif
262 
263 # if defined(P99_AT_LOAD_DECLARE)
264 
266 P99_AT_LOAD_DECLARE(p99_init_main);
267 
271  P99_FOR(, P99_MAX_NUMBER, P00_SEP, P00_INIT_TRIGGER_FUNCTION_1, P99_REP(P99_MAX_NUMBER,));
272 }
273 
276 void p00_init_func_p99_init_main(int * p00_argc, char***p00_argv) {
277  P99_UNUSED(p00_argc);
278  P99_UNUSED(p00_argv);
279 }
280 
281 # else
282 
283 # warning "no native load time launcher found, trying to intercept main"
284 
286  P99_FOR(, P99_MAX_NUMBER, P00_SEP, P00_INIT_TRIGGER_FUNCTION_1, P99_REP(P99_MAX_NUMBER,));
287  P99_FOR(, P99_MAX_NUMBER, P00_SEP, P00_INIT_TRIGGER_FUNCTION_2, P99_REP(P99_MAX_NUMBER,));
288 }
289 
290 # if defined(P99_INTERCEPT_MAIN)
291 # undef main
292 # define main p99_init_main
293 # endif
294 # endif
295 
296 
301 #endif
302 
303 #if P99_PASTE2(P00_INIT_1, 0) == 0
304 # undef P00_INIT_1
305 # define P00_INIT_1 1
306 #elif P00_INIT_1 == 1
307 # undef P00_INIT_1
308 # define P00_INIT_1 2
309 #elif P00_INIT_1 == 2
310 # undef P00_INIT_1
311 # define P00_INIT_1 3
312 #elif P00_INIT_1 == 3
313 # undef P00_INIT_1
314 # define P00_INIT_1 4
315 #elif P00_INIT_1 == 4
316 # undef P00_INIT_1
317 # define P00_INIT_1 5
318 #elif P00_INIT_1 == 5
319 # undef P00_INIT_1
320 # define P00_INIT_1 6
321 #elif P00_INIT_1 == 6
322 # undef P00_INIT_1
323 # define P00_INIT_1 7
324 #elif P00_INIT_1 == 7
325 # undef P00_INIT_1
326 # define P00_INIT_1 8
327 #elif P00_INIT_1 == 8
328 # undef P00_INIT_1
329 # define P00_INIT_1 9
330 #elif P00_INIT_1 == 9
331 # undef P00_INIT_1
332 # define P00_INIT_1 0
333 # if P99_PASTE2(P00_INIT_2, 0) == 0
334 # undef P00_INIT_2
335 # define P00_INIT_2 1
336 # elif P00_INIT_2 == 1
337 # undef P00_INIT_2
338 # define P00_INIT_2 2
339 # elif P00_INIT_2 == 2
340 # undef P00_INIT_2
341 # define P00_INIT_2 3
342 # elif P00_INIT_2 == 3
343 # undef P00_INIT_2
344 # define P00_INIT_2 4
345 # elif P00_INIT_2 == 4
346 # undef P00_INIT_2
347 # define P00_INIT_2 5
348 # elif P00_INIT_2 == 5
349 # undef P00_INIT_2
350 # define P00_INIT_2 6
351 # elif P00_INIT_2 == 6
352 # undef P00_INIT_2
353 # define P00_INIT_2 7
354 # elif P00_INIT_2 == 7
355 # undef P00_INIT_2
356 # define P00_INIT_2 8
357 # elif P00_INIT_2 == 8
358 # undef P00_INIT_2
359 # define P00_INIT_2 9
360 # elif P00_INIT_2 == 9
361 # undef P00_INIT_2
362 # define P00_INIT_2 0
363 # if P99_PASTE2(P00_INIT_3, 0) == 0
364 # undef P00_INIT_3
365 # define P00_INIT_3 1
366 # elif P00_INIT_3 == 1
367 # undef P00_INIT_3
368 # define P00_INIT_3 2
369 # elif P00_INIT_3 == 2
370 # undef P00_INIT_3
371 # define P00_INIT_3 3
372 # elif P00_INIT_3 == 3
373 # undef P00_INIT_3
374 # define P00_INIT_3 4
375 # elif P00_INIT_3 == 4
376 # undef P00_INIT_3
377 # define P00_INIT_3 5
378 # elif P00_INIT_3 == 5
379 # undef P00_INIT_3
380 # define P00_INIT_3 6
381 # elif P00_INIT_3 == 6
382 # undef P00_INIT_3
383 # define P00_INIT_3 7
384 # elif P00_INIT_3 == 7
385 # undef P00_INIT_3
386 # define P00_INIT_3 8
387 # elif P00_INIT_3 == 8
388 # undef P00_INIT_3
389 # define P00_INIT_3 9
390 # elif P00_INIT_3 == 9
391 # error "more than 999 init functions, compilation aborted"
392 # endif
393 # endif
394 #endif
395 
396 #if P00_INIT_NR > P99_MAX_NUMBER
397 # error "more init functions than supported through P99_MAX_NUMBER, compilation aborted"
398 #endif
p99_init_main
int p99_init_main(int, char *[])
P99_MAIN_INTERCEPT
#define P99_MAIN_INTERCEPT(NAME)
Intercept the main function before it is called and run some startup code.
Definition: p99_init.h:238
P99_REP
#define P99_REP(...)
p99_if.h
preprocessor conditionals to use inside macros
p99_inline
#define p99_inline
Try to force a function always to be inlined.
Definition: p99_compiler.h:496
P99_UNUSED
#define P99_UNUSED(...)
check if the list of expressions is syntactically valid but don't evaluate it
Definition: p99_enum.h:215
P99_WEAK
#define P99_WEAK(...)
Declare a symbol to be weak such that it can be provided several times without error.
Definition: p99_compiler.h:561
P99_CONST_FUNCTION
#define P99_CONST_FUNCTION
On architectures that support this, assert that a function is "const", i.e only depends on parameters...
Definition: p99_compiler.h:622
P99_MAX_NUMBER
#define P99_MAX_NUMBER
The maximal number of arguments the P99 macros can handle.
Definition: p99_generated.h:60
p99_hook.h
Compiler specific hook functions to execute at load/unload time.
p99_callback.h
P99_AT_LOAD_DEFINE
#define P99_AT_LOAD_DEFINE
P99_FOR
#define P99_FOR(NAME, N, OP, FUNC,...)
A preprocessor pseudo iterator.
Definition: p99_for.h:92