4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2004 Giovanni Bajo
30 * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
31 * All Rights Reserved.
33 * This module permits to create hunks for the functions that must be executed through
34 * RPC commands. For instance, given this code:
37 * ResultCode cmd_add(long a, long b, long* result);
38 * DECLARE_COMMAND_HUNK(add, (long)(long)(NIL), (long)(NIL));
39 * // ^ parameters ^ return values
42 * The macro is expanded to:
45 * ResultCode cmd_add_hunk(params argv[], params results[])
47 * return cmd_add(argv[0].l, argv[1].l, &results[0].l);
50 * const struct CmdTemplate cmd_add_template =
52 * "add", "dd", "d", cmd_add_hunk
56 * which is all the boilerplate needed to make the function ready for the RPC.
57 * The implementation uses the Boost Preprocessor Library (part of the Boost
58 * library, available at http://www.boost.org). The version we developed the
63 * \author Giovanni Bajo <rasky@develer.com>
65 * \brief Preprocessor magic to create hunks for the commands executed from the parser
71 *#* Revision 1.2 2006/07/19 12:56:27 bernie
72 *#* Convert to new Doxygen style.
74 *#* Revision 1.1 2006/06/01 12:27:39 marco
75 *#* Added utilities for protocols
77 *#* Revision 1.8 2005/01/12 20:06:31 rasky
78 *#* enum ResultCode è ora un typedef
80 *#* Revision 1.7 2004/12/14 15:10:53 user1
81 *#* Bernardo e Francesco: Assegnazione di un codice di ritorno ai processi
83 *#* Revision 1.6 2004/12/02 17:43:15 rasky
84 *#* Aggiunta la possibilità di settare le flag dei comandi con la nuova macro DECLARE_CMD_HUNK_FLAGS (altrimenti, il default è zero)
86 *#* Revision 1.5 2004/10/16 13:20:15 rasky
87 *#* Aggiunto supporto per alias di uno stesso comando
89 *#* Revision 1.4 2004/08/25 14:17:10 rasky
90 *#* Aggiornato il comment block dei log RCS
92 *#* Revision 1.3 2004/07/31 22:00:07 rasky
93 *#* Fixata una dipendenza
95 *#* Revision 1.2 2004/07/31 14:32:58 rasky
96 *#* args e results possono overlapparsi sempre grazie ai thunk generati: eliminati i due array separati per risparmiare memoria
98 *#* Revision 1.1 2004/05/22 16:29:16 rasky
99 *#* Generazione degli hunk dei comandi RPC tramite preprocessore
108 // Bring in the Boost Preprocess Library
109 #include <boost/preprocessor/library.hpp>
111 #define HUNK_INDEX_FOR_NIL 0
112 #define HUNK_INDEX_FOR_string 1
113 #define HUNK_INDEX_FOR_long 2
114 #define HUNK_ARRAY_LETTERS (3, (NIL, s, l))
115 #define HUNK_ARRAY_STRINGS (3, ("", "s", "d"))
117 // Transform int->l, float->f, etc.
118 #define HUNK_TYPE_LETTER(s, _, type) \
119 BOOST_PP_CAT(HUNK_INDEX_FOR_, type) \
122 #define HUNK_TRANSFORMER(_, array, elem) \
123 BOOST_PP_ARRAY_ELEM(elem, array) \
126 #define HUNK_SEQ_TRANS_ARRAY(seq, array) \
127 BOOST_PP_SEQ_TRANSFORM(HUNK_TRANSFORMER, array, seq) \
130 #define HUNK_PARAM(_, n, seq) \
131 args_results[n+1]. BOOST_PP_SEQ_ELEM(n, seq) \
134 #define HUNK_RESULT(_, n, seq) \
135 &args_results[n]. BOOST_PP_SEQ_ELEM(n, seq) \
138 #define HUNK_IDENTITY(_, dummy, x) x
139 #define CMD_HUNK_TEMPLATE(func) cmd_##func###_template
141 #define DECLARE_CMD_HUNK_2(func, name, param_types, result_types, flags) \
142 static ResultCode cmd_##name##_hunk(parms args_results[]) \
145 BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), HUNK_PARAM, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_LETTERS)) \
146 BOOST_PP_COMMA_IF(BOOST_PP_AND(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(param_types)), BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)))) \
147 BOOST_PP_ENUM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(result_types)), HUNK_RESULT, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_LETTERS)) \
150 const struct CmdTemplate CMD_HUNK_TEMPLATE(name) = { \
152 BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(param_types, HUNK_ARRAY_STRINGS)), \
153 BOOST_PP_SEQ_FOR_EACH(HUNK_IDENTITY, _, HUNK_SEQ_TRANS_ARRAY(result_types, HUNK_ARRAY_STRINGS)), \
159 #define DECLARE_CMD_HUNK(func, param_types, result_types) \
160 DECLARE_CMD_HUNK_2(func, func, \
161 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
162 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
166 #define DECLARE_CMD_HUNK_NAME(func, name, param_types, result_types) \
167 DECLARE_CMD_HUNK_2(func, name, \
168 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
169 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \
173 #define DECLARE_CMD_HUNK_FLAGS(func, param_types, result_types, flags) \
174 DECLARE_CMD_HUNK_2(func, func, \
175 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, param_types), \
176 BOOST_PP_SEQ_TRANSFORM(HUNK_TYPE_LETTER, _, result_types), \