valparam.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /**
  2. * \file libyasm/valparam.h
  3. * \brief YASM value/parameter interface.
  4. *
  5. * \license
  6. * Copyright (C) 2001-2007 Peter Johnson
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * - Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * - Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. * \endlicense
  29. */
  30. #ifndef YASM_VALPARAM_H
  31. #define YASM_VALPARAM_H
  32. #ifndef YASM_LIB_DECL
  33. #define YASM_LIB_DECL
  34. #endif
  35. /** Value/parameter pair. \internal */
  36. struct yasm_valparam {
  37. /*@reldef@*/ STAILQ_ENTRY(yasm_valparam) link; /**< Next pair in list */
  38. /*@owned@*/ /*@null@*/ char *val; /**< Value */
  39. /** Parameter type. */
  40. enum yasm_param_type {
  41. YASM_PARAM_ID, /**< Identifier */
  42. YASM_PARAM_STRING, /**< String */
  43. YASM_PARAM_EXPR /**< Expression */
  44. } type; /**< Parameter type */
  45. /** Parameter value. */
  46. union yasm_param {
  47. /*@owned@*/ char *id; /**< Identifier */
  48. /*@owned@*/ char *str; /**< String */
  49. /*@owned@*/ yasm_expr *e; /**< Expression */
  50. } param; /**< Parameter */
  51. /** Prefix character that indicates a raw identifier. When
  52. * yasm_vp_string() is called on a #YASM_PARAM_ID, all characters are
  53. * returned. When yasm_vp_id() is called on a #YASM_PARAM_ID, if the
  54. * identifier begins with this character, this character is stripped
  55. * from the returned value.
  56. */
  57. char id_prefix;
  58. };
  59. /** Linked list of value/parameter pairs. \internal */
  60. /*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam);
  61. /** Directive list entry structure. */
  62. struct yasm_directive {
  63. /** Directive name. GAS directives should include the ".", NASM
  64. * directives should just be the raw name (not including the []).
  65. * NULL entry required to terminate list of directives.
  66. */
  67. /*@null@*/ const char *name;
  68. const char *parser; /**< Parser keyword */
  69. /** Handler callback function for the directive.
  70. * \param object object
  71. * \param valparams value/parameters
  72. * \param objext_valparams object format-specific value/parameters
  73. * \param line virtual line (from yasm_linemap)
  74. */
  75. void (*handler) (yasm_object *object, yasm_valparamhead *valparams,
  76. yasm_valparamhead *objext_valparams, unsigned long line);
  77. /** Flags for pre-handler parameter checking. */
  78. enum yasm_directive_flags {
  79. YASM_DIR_ANY = 0, /**< Any valparams accepted */
  80. YASM_DIR_ARG_REQUIRED = 1, /**< Require at least 1 valparam */
  81. YASM_DIR_ID_REQUIRED = 2 /**< First valparam must be ID */
  82. } flags;
  83. };
  84. /** Call a directive. Performs any valparam checks asked for by the
  85. * directive prior to call. Note that for a variety of reasons, a directive
  86. * can generate an error.
  87. * \param directive directive
  88. * \param object object
  89. * \param valparams value/parameters
  90. * \param objext_valparams object format-specific value/parameters
  91. * \param line virtual line (from yasm_linemap)
  92. */
  93. YASM_LIB_DECL
  94. void yasm_call_directive(const yasm_directive *directive, yasm_object *object,
  95. yasm_valparamhead *valparams,
  96. yasm_valparamhead *objext_valparams,
  97. unsigned long line);
  98. /** Create a new valparam with identifier parameter.
  99. * \param v value
  100. * \param p parameter
  101. * \param id_prefix identifier prefix for raw identifiers
  102. * \return Newly allocated valparam.
  103. */
  104. YASM_LIB_DECL
  105. yasm_valparam *yasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p,
  106. int id_prefix);
  107. /** Create a new valparam with string parameter.
  108. * \param v value
  109. * \param p parameter
  110. * \return Newly allocated valparam.
  111. */
  112. YASM_LIB_DECL
  113. yasm_valparam *yasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p);
  114. /** Create a new valparam with expression parameter.
  115. * \param v value
  116. * \param p parameter
  117. * \return Newly allocated valparam.
  118. */
  119. YASM_LIB_DECL
  120. yasm_valparam *yasm_vp_create_expr(/*@keep@*/ char *v,
  121. /*@keep@*/ yasm_expr *p);
  122. /** Get a valparam parameter as an expr. If the parameter is an identifier,
  123. * it's treated as a symbol (yasm_symtab_use() is called to convert it).
  124. * \param vp valparam
  125. * \param symtab symbol table
  126. * \param line virtual line
  127. * \return Expression, or NULL if vp is NULL or the parameter cannot be
  128. * converted to an expression.
  129. */
  130. YASM_LIB_DECL
  131. /*@null@*/ /*@only@*/ yasm_expr *yasm_vp_expr
  132. (const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line);
  133. /** Get a valparam parameter as a string. If the parameter is an identifier,
  134. * it's treated as a string.
  135. * \param vp valparam
  136. * \return String, or NULL if vp is NULL or the parameter cannot be realized
  137. * as a string.
  138. */
  139. YASM_LIB_DECL
  140. /*@null@*/ /*@dependent@*/ const char *yasm_vp_string(const yasm_valparam *vp);
  141. /** Get a valparam parameter as an identifier.
  142. * \param vp valparam
  143. * \return Identifier (string), or NULL if vp is NULL or the parameter is not
  144. * an identifier.
  145. */
  146. YASM_LIB_DECL
  147. /*@null@*/ /*@dependent@*/ const char *yasm_vp_id(const yasm_valparam *vp);
  148. /** Create a new linked list of valparams.
  149. * \return Newly allocated valparam list.
  150. */
  151. YASM_LIB_DECL
  152. yasm_valparamhead *yasm_vps_create(void);
  153. /** Destroy a list of valparams (created with yasm_vps_create).
  154. * \param headp list of valparams
  155. */
  156. YASM_LIB_DECL
  157. void yasm_vps_destroy(yasm_valparamhead *headp);
  158. /** Initialize linked list of valparams.
  159. * \param headp linked list
  160. */
  161. void yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
  162. #ifndef YASM_DOXYGEN
  163. #define yasm_vps_initialize(headp) STAILQ_INIT(headp)
  164. #endif
  165. /** Destroy (free allocated memory for) linked list of valparams (created with
  166. * yasm_vps_initialize).
  167. * \warning Deletes val/params.
  168. * \param headp linked list
  169. */
  170. YASM_LIB_DECL
  171. void yasm_vps_delete(yasm_valparamhead *headp);
  172. /** Append valparam to tail of linked list.
  173. * \param headp linked list
  174. * \param vp valparam
  175. */
  176. void yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
  177. #ifndef YASM_DOXYGEN
  178. #define yasm_vps_append(headp, vp) do { \
  179. if (vp) \
  180. STAILQ_INSERT_TAIL(headp, vp, link); \
  181. } while(0)
  182. #endif
  183. /** Get first valparam in linked list.
  184. * \param headp linked list
  185. * \return First valparam in linked list.
  186. */
  187. /*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_first
  188. (yasm_valparamhead *headp);
  189. #ifndef YASM_DOXYGEN
  190. #define yasm_vps_first(headp) STAILQ_FIRST(headp)
  191. #endif
  192. /** Get next valparam in linked list.
  193. * \param cur previous valparam in linked list
  194. * \return Next valparam in linked list.
  195. */
  196. /*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_next(yasm_valparam *cur);
  197. #ifndef YASM_DOXYGEN
  198. #define yasm_vps_next(cur) STAILQ_NEXT(cur, link)
  199. #endif
  200. /** Iterate through linked list of valparams.
  201. * \internal
  202. * \param iter iterator variable
  203. * \param headp linked list
  204. */
  205. #ifndef YASM_DOXYGEN
  206. #define yasm_vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
  207. #endif
  208. /** Print linked list of valparams. For debugging purposes.
  209. * \param f file
  210. * \param headp linked list
  211. */
  212. YASM_LIB_DECL
  213. void yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
  214. /** Directive valparam parse helper structure. */
  215. typedef struct yasm_dir_help {
  216. /** Value portion of val=param (if needsparam=1), or standalone identifier
  217. * (if needsparam=0).
  218. */
  219. const char *name;
  220. /** 1 if value requires parameter, 0 if it must not have a parameter. */
  221. int needsparam;
  222. /** Helper callback function if name and parameter existence match.
  223. * \param obj obj passed into yasm_dir_helper()
  224. * \param vp value/parameter
  225. * \param line line passed into yasm_dir_helper()
  226. * \param data data passed into yasm_dir_helper() plus
  227. #yasm_dir_help.off offset
  228. * \param arg #yasm_dir_help.arg argument
  229. * \return -1 on error, 0 otherwise.
  230. */
  231. int (*helper) (void *obj, yasm_valparam *vp, unsigned long line,
  232. void *data, uintptr_t arg);
  233. /** Offset added to data pointer passed into yasm_dir_helper() before
  234. * data pointer is given to #yasm_dir_help.helper(). This is so that
  235. * a structure can be passed into yasm_dir_helper() and this can be an
  236. * offsetof() to point the helper function to a specific structure
  237. * member.
  238. */
  239. size_t off;
  240. /** Argument to pass in as the arg parameter to #yasm_dir_help.helper().
  241. */
  242. uintptr_t arg;
  243. } yasm_dir_help;
  244. /** Help parse a list of directive value/parameters. Takes an array of
  245. * #yasm_dir_help structures and tries to match val=param (or just val)
  246. * against the passed value/parameters. When no match is found in the
  247. * array of help structures, calls helper_valparam.
  248. * \param obj object to be passed to yasm_dir_help.helper() or
  249. * helper_valparam() callback
  250. * \param vp_first first value/parameter to examine
  251. * \param line virtual line number; passed down to helper callback
  252. * \param help array of #yasm_dir_help structures
  253. * \param nhelp number of array elements
  254. * \param data base data pointer; if a match is found,
  255. * the respective #yasm_dir_help.off is added to this
  256. * prior to it being passed to the helper callback
  257. * \param helper_valparam catch-all callback; should return -1 on error,
  258. * 0 if not matched, 1 if matched.
  259. * \return -1 on error, 1 if any arguments matched (including via
  260. * catch-all callback), 0 if no match.
  261. */
  262. YASM_LIB_DECL
  263. int yasm_dir_helper(void *obj, yasm_valparam *vp_first, unsigned long line,
  264. const yasm_dir_help *help, size_t nhelp, void *data,
  265. int (*helper_valparam) (void *object,
  266. yasm_valparam *vp,
  267. unsigned long line,
  268. void *data));
  269. /** Standard helper for yasm_dir_helper() that simply sets a flag when called.
  270. * It does not look at the vp; rather, it uses the value of the arg parameter,
  271. * and stores an unsigned long value to data.
  272. * \param obj unused
  273. * \param vp unused
  274. * \param line unused
  275. * \param data pointer to an unsigned long
  276. * \param arg flag to set
  277. * \return 0
  278. */
  279. YASM_LIB_DECL
  280. int yasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
  281. void *data, uintptr_t arg);
  282. /** Standard helper for yasm_dir_helper() that simply ORs a flag when called.
  283. * It does not look at the vp; rather, it uses the value of the arg parameter,
  284. * and ORs it with the unsigned long value in data.
  285. * \param obj unused
  286. * \param vp unused
  287. * \param line unused
  288. * \param data pointer to an unsigned long
  289. * \param arg flag to OR
  290. * \return 0
  291. */
  292. YASM_LIB_DECL
  293. int yasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
  294. void *data, uintptr_t arg);
  295. /** Standard helper for yasm_dir_helper() that simply ANDs a flag when called.
  296. * It does not look at the vp; rather, it uses the value of the arg parameter,
  297. * and ANDs its inverse (~) with the unsigned long value in data.
  298. * \param obj unused
  299. * \param vp unused
  300. * \param line unused
  301. * \param data pointer to an unsigned long
  302. * \param arg flag to AND
  303. * \return 0
  304. */
  305. YASM_LIB_DECL
  306. int yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
  307. void *data, uintptr_t arg);
  308. /** Standard helper for yasm_dir_helper() that parses an expr parameter.
  309. * The #yasm_dir_help structure that uses this function should have
  310. * needsparam=1. The obj parameter to yasm_dir_helper() when this helper
  311. * is used MUST point to a #yasm_object. In addition, the data parameter
  312. * that is ultimately passed to this function (e.g. yasm_dir_helper() data
  313. * parameter plus #yasm_dir_help.off) must point to a #yasm_expr *
  314. * initialized to NULL.
  315. * \param obj object; must be #yasm_object
  316. * \param vp valparam
  317. * \param line virtual line number
  318. * \param data pointer to #yasm_expr *
  319. * \param arg unused argument
  320. * \return -1 on error, 0 otherwise.
  321. */
  322. YASM_LIB_DECL
  323. int yasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
  324. void *data, uintptr_t arg);
  325. /** Standard helper for yasm_dir_helper() that parses an intnum parameter.
  326. * The #yasm_dir_help structure that uses this function should have
  327. * needsparam=1. The obj parameter to yasm_dir_helper() when this helper
  328. * is used MUST point to a #yasm_object. In addition, the data parameter
  329. * that is ultimately passed to this function (e.g. yasm_dir_helper() data
  330. * parameter plus #yasm_dir_help.off) must point to a #yasm_intnum *
  331. * initialized to NULL.
  332. * \param obj object; must be #yasm_object
  333. * \param vp valparam
  334. * \param line virtual line number
  335. * \param data pointer to #yasm_intnum *
  336. * \param arg unused argument
  337. * \return -1 on error, 0 otherwise.
  338. */
  339. YASM_LIB_DECL
  340. int yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
  341. void *data, uintptr_t arg);
  342. /** Standard helper for yasm_dir_helper() that parses an string (or
  343. * standalone identifier) parameter.
  344. * The #yasm_dir_help structure that uses this function should have
  345. * needsparam=1. The data parameter that is ultimately passed to this
  346. * function (e.g. yasm_dir_helper() data parameter plus #yasm_dir_help.off)
  347. * must point to a char * initialized to NULL.
  348. * \param obj unused
  349. * \param vp valparam
  350. * \param line unused
  351. * \param data pointer to char *
  352. * \param arg unused
  353. * \return -1 on error, 0 otherwise.
  354. */
  355. YASM_LIB_DECL
  356. int yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
  357. void *data, uintptr_t arg);
  358. /** Standard catch-all callback fro yasm_dir_helper(). Generates standard
  359. * warning for all valparams.
  360. * \param obj unused
  361. * \param vp valparam
  362. * \param line unused
  363. * \param data unused
  364. * \return 0
  365. */
  366. YASM_LIB_DECL
  367. int yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
  368. unsigned long line, void *data);
  369. #endif