| /*****************************************************************************\ |
| * parsers.h - Slurm data parsing handlers |
| ***************************************************************************** |
| * Copyright (C) SchedMD LLC. |
| * |
| * This file is part of Slurm, a resource management program. |
| * For details, see <https://slurm.schedmd.com/>. |
| * Please also read the included file: DISCLAIMER. |
| * |
| * Slurm is free software; you can redistribute it and/or modify it under |
| * the terms of the GNU General Public License as published by the Free |
| * Software Foundation; either version 2 of the License, or (at your option) |
| * any later version. |
| * |
| * In addition, as a special exception, the copyright holders give permission |
| * to link the code of portions of this program with the OpenSSL library under |
| * certain conditions as described in each individual source file, and |
| * distribute linked combinations including the two. You must obey the GNU |
| * General Public License in all respects for all of the code used other than |
| * OpenSSL. If you modify file(s) with this exception, you may extend this |
| * exception to your version of the file(s), but you are not obligated to do |
| * so. If you do not wish to do so, delete this exception statement from your |
| * version. If you delete this exception statement from all source files in |
| * the program, then also delete it here. |
| * |
| * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| * details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with Slurm; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| \*****************************************************************************/ |
| |
| #ifndef DATA_PARSER_PARSERS |
| #define DATA_PARSER_PARSERS |
| |
| #include "api.h" |
| #include "src/interfaces/data_parser.h" |
| #include "src/slurmrestd/openapi.h" |
| |
| typedef data_parser_type_t type_t; |
| typedef struct parser_s parser_t; |
| |
| typedef enum { |
| NEED_NONE = 0, /* parser has no pre-reqs for data */ |
| NEED_TRES = SLURM_BIT(1), |
| NEED_QOS = SLURM_BIT(2), |
| } need_t; |
| |
| typedef enum { |
| FLAG_BIT_TYPE_INVALID = 0, /* aka not initialized */ |
| FLAG_BIT_TYPE_EQUAL, /* entire masked value must match for flag */ |
| FLAG_BIT_TYPE_BIT, /* only need bit(s) to match */ |
| FLAG_BIT_TYPE_REMOVED, /* flag removed but needs to still parse correct */ |
| FLAG_BIT_TYPE_MAX /* place holder */ |
| } flag_bit_type_t; |
| |
| #define MAGIC_FLAG_BIT 0xa11a3a05 |
| |
| typedef struct { |
| int magic; /* MAGIC_FLAG_BIT */ |
| char *name; |
| flag_bit_type_t type; |
| uint64_t mask; /* avoid changing any bits not in mask */ |
| size_t mask_size; |
| char *mask_name; |
| uint64_t value; /* bits set by flag */ |
| char *flag_name; |
| size_t flag_size; |
| const char *description; |
| bool hidden; /* hide from OpenAPI spec generation */ |
| uint16_t deprecated; /* protocol version when deprecated */ |
| } flag_bit_t; |
| |
| typedef enum { |
| PARSER_MODEL_INVALID = 0, /* aka not initialized */ |
| PARSER_MODEL_ARRAY, /* parser array to parse every field in a struct */ |
| PARSER_MODEL_ARRAY_LINKED_FIELD, /* link to parser in a parser array */ |
| PARSER_MODEL_ARRAY_LINKED_EXPLODED_FLAG_ARRAY_FIELD, /* link to parser in a parser array of exploded flag array */ |
| PARSER_MODEL_ARRAY_SKIP_FIELD, /* parser to mark field as not being parsed in a parser array */ |
| PARSER_MODEL_ARRAY_REMOVED_FIELD, /* parser to mark field as placeholder for field already removed from struct */ |
| |
| PARSER_MODEL_SIMPLE, /* parser for single field in struct */ |
| PARSER_MODEL_COMPLEX, /* parser for uses multiple fields in struct */ |
| PARSER_MODEL_FLAG_ARRAY, /* parser for list of flags */ |
| PARSER_MODEL_LIST, /* parser for list_t's */ |
| PARSER_MODEL_PTR, /* parser for pointer */ |
| PARSER_MODEL_NT_PTR_ARRAY, /* parser for NULL terminated array of pointers */ |
| /* NT_ARRAY objects must not require an special initializer */ |
| PARSER_MODEL_NT_ARRAY, /* parser for NULL terminated array of objects */ |
| PARSER_MODEL_REMOVED, /* parser for removed types */ |
| |
| /* |
| * Alias for another parser. |
| * |
| * Only for use in maintaining the same OAS name when a new parser name |
| * is needed in newer plugins. |
| */ |
| PARSER_MODEL_ALIAS, |
| |
| PARSER_MODEL_MAX /* place holder */ |
| } parser_model_t; |
| |
| #define MAGIC_PARSER 0xa3bafa05 |
| |
| typedef void *(*parser_new_func_t)(void); |
| /* must be compatible with ListDelF */ |
| typedef void (*parser_free_func_t)(void *ptr); |
| |
| typedef struct parser_s { |
| int magic; /* MAGIC_PARSER */ |
| parser_model_t model; |
| |
| /* common model properties ------------------------------------------ */ |
| type_t type; |
| char *type_string; /* stringified DATA_PARSE enum */ |
| const char *obj_desc; /* description of object */ |
| char *obj_type_string; /* stringified C type */ |
| openapi_type_format_t obj_openapi; /* OpenAPI format for object */ |
| ssize_t size; /* size of target obj */ |
| parser_new_func_t new; /* function to create new instance of obj being pointed at */ |
| parser_free_func_t free; /* function to release instance of obj being pointed at */ |
| uint16_t deprecated; /* protocol version when deprecated */ |
| |
| /* Linked model properties ------------------------------------------ */ |
| char *field_name; /* name of field in struct if there is a ptr_offset */ |
| uint8_t field_name_overloads; /* number of other parsers using same field name */ |
| char *key; /* path of field key in dictionary */ |
| ssize_t ptr_offset; /* offset from parent object or NO_VAL */ |
| bool required; |
| |
| /* Alias model properties ----------------------------------------- */ |
| type_t alias_type; |
| |
| /* Pointer model properties ----------------------------------------- */ |
| type_t pointer_type; |
| bool allow_null_pointer; /* leave destination as null type when source pointer is NULL while dumping */ |
| |
| /* NULL terminated array of pointers model properties --------------- */ |
| type_t array_type; |
| |
| /* Flag array model properties -------------------------------------- */ |
| const flag_bit_t *flag_bit_array; |
| uint8_t flag_bit_array_count; /* number of entries in flag_bit_array */ |
| bool single_flag; /* false to be list or true to be string for 1 flag */ |
| |
| /* List model properties -------------------------------------------- */ |
| type_t list_type; |
| |
| /* Array model properties ------------------------------------------- */ |
| const parser_t *const fields; /* pointer to array of parsers for each field */ |
| const size_t field_count; /* number of fields in fields array */ |
| |
| /* Simple and Complex model properties ------------------------------ */ |
| int (*dump)(const parser_t *const parser, void *src, data_t *dst, |
| args_t *args); |
| int (*parse)(const parser_t *const parser, void *dst, data_t *src, |
| args_t *args, data_t *parent_path); |
| need_t needs; |
| } parser_t; |
| |
| /* |
| * Called at startup to run any setup of parsers and testing |
| */ |
| extern void parsers_init(void); |
| |
| #ifndef NDEBUG |
| extern void check_parser_funcname(const parser_t *const parser, |
| const char *func_name); |
| #define check_parser(parser) check_parser_funcname(parser, __func__) |
| |
| /* |
| * Verify that the parser is sliced parser from an array. |
| * |
| * Allow enforcement that certain parsers should only ever be in an parser array |
| * and never as a directly reference-able parser (such as flags) |
| */ |
| extern void verify_parser_sliced_funcname(const parser_t *const parser, |
| const char *func, const char *file, |
| int line); |
| #define verify_parser_sliced(parser) \ |
| verify_parser_sliced_funcname(parser, __func__, __FILE__, __LINE__) |
| |
| /* |
| * Verify that the parser is not a sliced parser from an array. Parsers inside |
| * of arrays are only meant to act as link and definition of where the offset is |
| * to the field. Directly referencing them is always an bug. Use |
| * find_parser_by_type() to find the correct parser for that type instead. |
| */ |
| extern void verify_parser_not_sliced_funcname(const parser_t *const parser, |
| const char *func, |
| const char *file, int line); |
| #define verify_parser_not_sliced(parser) \ |
| verify_parser_not_sliced_funcname(parser, __func__, __FILE__, __LINE__) |
| #else |
| #define check_parser(parser) {} |
| #define verify_parser_not_sliced(parser) {} |
| #define verify_parser_sliced(parser) {} |
| #endif |
| |
| extern const parser_t *const find_parser_by_type(type_t type); |
| |
| /* |
| * Resolve aliased or pointer model parsers to final unaliased parser |
| */ |
| extern const parser_t *unalias_parser(const parser_t *parser); |
| |
| extern void get_parsers(const parser_t **parsers_ptr, int *count_ptr); |
| |
| #endif |