From 5662eb0df6c47d0e391de43887c7433912863514 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Tue, 3 Nov 2020 14:12:01 +0100 Subject: [PATCH 8/8] porting/dpl: add riot files --- porting/dpl/riot/include/config/config.h | 369 ++++++++++++++++ porting/dpl/riot/include/dpl/queue.h | 525 +++++++++++++++++++++++ porting/dpl/riot/src/config.c | 83 ++++ 3 files changed, 977 insertions(+) create mode 100644 porting/dpl/riot/include/config/config.h create mode 100644 porting/dpl/riot/include/dpl/queue.h create mode 100644 porting/dpl/riot/src/config.c diff --git a/porting/dpl/riot/include/config/config.h b/porting/dpl/riot/include/config/config.h new file mode 100644 index 0000000..4dc4b69 --- /dev/null +++ b/porting/dpl/riot/include/config/config.h @@ -0,0 +1,369 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#ifndef __SYS_CONFIG_H_ +#define __SYS_CONFIG_H_ + +/** + * @addtogroup SysConfig Configuration of Apache Mynewt System + * @{ + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +#define CONF_MAX_DIR_DEPTH 8 /* max depth of config tree */ +#define CONF_MAX_NAME_LEN (8 * CONF_MAX_DIR_DEPTH) +#define CONF_MAX_VAL_LEN 256 +#define CONF_NAME_SEPARATOR "/" + +#define CONF_NMGR_OP 0 + +/** @endcond */ + +/** + * Type of configuration value. + */ +typedef enum conf_type { + CONF_NONE = 0, + CONF_DIR, + /** 8-bit signed integer */ + CONF_INT8, + /** 16-bit signed integer */ + CONF_INT16, + /** 32-bit signed integer */ + CONF_INT32, + /** 64-bit signed integer */ + CONF_INT64, + /** String */ + CONF_STRING, + /** Bytes */ + CONF_BYTES, + /** Floating point */ + CONF_FLOAT, + /** Double precision */ + CONF_DOUBLE, + /** Boolean */ + CONF_BOOL, +} __attribute__((__packed__)) conf_type_t; + +/** + * Parameter to commit handler describing where data is going to. + */ +enum conf_export_tgt { + /** Value is to be persisted */ + CONF_EXPORT_PERSIST, + /** Value is to be display */ + CONF_EXPORT_SHOW +}; + +typedef enum conf_export_tgt conf_export_tgt_t; + +/** + * Handler for getting configuration items, this handler is called + * per-configuration section. Configuration sections are delimited + * by '/', for example: + * + * - section/name/value + * + * Would be passed as: + * + * - argc = 3 + * - argv[0] = section + * - argv[1] = name + * - argv[2] = value + * + * The handler returns the value into val, null terminated, up to + * val_len_max. + * + * @param argc The number of sections in the configuration variable + * @param argv The array of configuration sections + * @param val A pointer to the buffer to return the configuration + * value into. + * @param val_len_max The maximum length of the val buffer to copy into. + * + * @return A pointer to val or NULL if error. + */ +typedef char *(*conf_get_handler_t)(int argc, char **argv, char *val, int val_len_max); + +/** + * Set the configuration variable pointed to by argc and argv. See + * description of ch_get_handler_t for format of these variables. This sets the + * configuration variable to the shadow value, but does not apply the configuration + * change. In order to apply the change, call the ch_commit() handler. + * + * @param argc The number of sections in the configuration variable. + * @param argv The array of configuration sections + * @param val The value to configure that variable to + * + * @return 0 on success, non-zero error code on failure. + */ +typedef int (*conf_set_handler_t)(int argc, char **argv, char *val); + +/** + * Commit shadow configuration state to the active configuration. + * + * @return 0 on success, non-zero error code on failure. + */ +typedef int (*conf_commit_handler_t)(void); + +/** + * Called per-configuration variable being exported. + * + * @param name The name of the variable to export + * @param val The value of the variable to export + */ +typedef void (*conf_export_func_t)(char *name, char *val); + +/** + * Export all of the configuration variables, calling the export_func + * per variable being exported. + * + * @param export_func The export function to call. + * @param tgt The target of the export, either for persistence or display. + * + * @return 0 on success, non-zero error code on failure. + */ +typedef int (*conf_export_handler_t)(conf_export_func_t export_func, + conf_export_tgt_t tgt); + +/** + * Configuration handler, used to register a config item/subtree. + */ +struct conf_handler { + SLIST_ENTRY(conf_handler) ch_list; + /** + * The name of the conifguration item/subtree + */ + char *ch_name; + /** Get configuration value */ + conf_get_handler_t ch_get; + /** Set configuration value */ + conf_set_handler_t ch_set; + /** Commit configuration value */ + conf_commit_handler_t ch_commit; + /** Export configuration value */ + conf_export_handler_t ch_export; +}; + +void conf_init(void); +void conf_store_init(void); + +/** + * Register a handler for configurations items. + * + * @param cf Structure containing registration info. + * + * @return 0 on success, non-zero on failure. + */ +//int conf_register(struct conf_handler *cf); +#define conf_register(__A) printf("%s:%d not implemented", __func__, __LINE__) + +/** + * Load configuration from registered persistence sources. Handlers for + * configuration subtrees registered earlier will be called for encountered + * values. + * + * @return 0 on success, non-zero on failure. + */ +int conf_load(void); + +/** + * Load configuration from a specific registered persistence source. + * Handlers will be called for configuration subtree for + * encountered values. + * + * @param name of the configuration subtree. + * @return 0 on success, non-zero on failure. + */ +int conf_load_one(char *name); + +/** + * @brief Loads the configuration if it hasn't been loaded since reboot. + * + * @return 0 on success, non-zero on failure. + */ +int conf_ensure_loaded(void); + +/** + * Config setting comes as a result of conf_load(). + * + * @return 1 if yes, 0 if not. + */ +int conf_set_from_storage(void); + +/** + * Save currently running configuration. All configuration which is different + * from currently persisted values will be saved. + * + * @return 0 on success, non-zero on failure. + */ +int conf_save(void); + +/** + * Save currently running configuration for configuration subtree. + * + * @param name Name of the configuration subtree. + * + * @return 0 on success, non-zero on failure. + */ +int conf_save_tree(char *name); + +/** + * Write a single configuration value to persisted storage (if it has + * changed value). + * + * @param name Name/key of the configuration item. + * @param var Value of the configuration item. + * + * @return 0 on success, non-zero on failure. + */ +int conf_save_one(const char *name, char *var); + +/** + * Set configuration item identified by @p name to be value @p val_str. + * This finds the configuration handler for this subtree and calls it's + * set handler. + * + * @param name Name/key of the configuration item. + * @param val_str Value of the configuration item. + * + * @return 0 on success, non-zero on failure. + */ +int conf_set_value(char *name, char *val_str); + +/** + * Get value of configuration item identified by @p name. + * This calls the configuration handler ch_get for the subtree. + * + * Configuration handler can copy the string to @p buf, the maximum + * number of bytes it will copy is limited by @p buf_len. + * + * Return value will be pointer to beginning of the value. Note that + * this might, or might not be the same as buf. + * + * @param name Name/key of the configuration item. + * @param val_str Value of the configuration item. + * + * @return pointer to value on success, NULL on failure. + */ +char *conf_get_value(char *name, char *buf, int buf_len); + +/** + * Get stored value of configuration item identified by @p name. + * This traverses the configuration area(s), and copies the value + * of the latest value. + * + * Value is copied to @p buf, the maximum number of bytes it will copy is + * limited by @p buf_len. + * + * @param name Name/key of the configuration item. + * @param val_str Value of the configuration item. + * + * @return 0 on success, non-zero on failure. + */ +int conf_get_stored_value(char *name, char *buf, int buf_len); + +/** + * Call commit for all configuration handler. This should apply all + * configuration which has been set, but not applied yet. + * + * @param name Name of the configuration subtree, or NULL to commit everything. + * + * @return 0 on success, non-zero on failure. + */ +int conf_commit(char *name); + +/** + * Convenience routine for converting value passed as a string to native + * data type. + * + * @param val_str Value of the configuration item as string. + * @param type Type of the value to convert to. + * @param vp Pointer to variable to fill with the decoded value. + * @param vp Size of that variable. + * + * @return 0 on success, non-zero on failure. + */ +int conf_value_from_str(char *val_str, enum conf_type type, void *vp, + int maxlen); + +/** + * Convenience routine for converting byte array passed as a base64 + * encoded string. + * + * @param val_str Value of the configuration item as string. + * @param vp Pointer to variable to fill with the decoded value. + * @param len Size of that variable. On return the number of bytes in the array. + * + * @return 0 on success, non-zero on failure. + */ +int conf_bytes_from_str(char *val_str, void *vp, int *len); + +/** + * Convenience routine for converting native data type to a string. + * + * @param type Type of the value to convert from. + * @param vp Pointer to variable to convert. + * @param buf Buffer where string value will be stored. + * @param buf_len Size of the buffer. + * + * @return 0 on success, non-zero on failure. + */ +char *conf_str_from_value(enum conf_type type, void *vp, char *buf, + int buf_len); + +/** Return the length of a configuration string from buffer length. */ +#define CONF_STR_FROM_BYTES_LEN(len) (((len) * 4 / 3) + 4) + +/** + * Convenience routine for converting byte array into a base64 + * encoded string. + * + * @param vp Pointer to variable to convert. + * @param vp_len Number of bytes to convert. + * @param buf Buffer where string value will be stored. + * @param buf_len Size of the buffer. + * + * @return 0 on success, non-zero on failure. + */ +char *conf_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len); + +/** + * Convert a string into a value of type + */ +#define CONF_VALUE_SET(str, type, val) \ + conf_value_from_str((str), (type), &(val), sizeof(val)) + +#ifdef __cplusplus +} +#endif + +/** + * @} SysConfig + */ + +#endif /* __SYS_CONFIG_H_ */ diff --git a/porting/dpl/riot/include/dpl/queue.h b/porting/dpl/riot/include/dpl/queue.h new file mode 100644 index 0000000..4e74970 --- /dev/null +++ b/porting/dpl/riot/include/dpl/queue.h @@ -0,0 +1,525 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ + */ + +#ifndef DPL_QUEUE_H +#define DPL_QUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This file defines five types of data structures: singly-linked lists, + * singly-linked tail queues, lists, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ CIRCLEQ + * _HEAD + + + + + + * _HEAD_INITIALIZER + + + + + + * _ENTRY + + + + + + * _INIT + + + + + + * _EMPTY + + + + + + * _FIRST + + + + + + * _NEXT + + + + + + * _PREV - - - + + + * _LAST - - + + + + * _FOREACH + + + + + + * _FOREACH_REVERSE - - - + + + * _INSERT_HEAD + + + + + + * _INSERT_BEFORE - + - + + + * _INSERT_AFTER + + + + + + * _INSERT_TAIL - - + + + + * _REMOVE_HEAD + - + - - + * _REMOVE + + + + + + * + */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = \ + SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ + } \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY(head) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD(head, field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + if ((STAILQ_NEXT(curelm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + } \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + + +#ifndef __KERNEL__ +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) +#endif + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ +} while (0) + +/* + * Circular queue declarations. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { (void *)&(head), (void *)&(head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) + +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for ((var) = CIRCLEQ_FIRST((head)); \ + (var) != (void *)(head) || ((var) = NULL); \ + (var) = CIRCLEQ_NEXT((var), field)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for ((var) = CIRCLEQ_LAST((head)); \ + (var) != (void *)(head) || ((var) = NULL); \ + (var) = CIRCLEQ_PREV((var), field)) + +#define CIRCLEQ_INIT(head) do { \ + CIRCLEQ_FIRST((head)) = (void *)(head); \ + CIRCLEQ_LAST((head)) = (void *)(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \ + CIRCLEQ_PREV((elm), field) = (listelm); \ + if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \ + CIRCLEQ_LAST((head)) = (elm); \ + else \ + CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\ + CIRCLEQ_NEXT((listelm), field) = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + CIRCLEQ_NEXT((elm), field) = (listelm); \ + CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \ + if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \ + CIRCLEQ_FIRST((head)) = (elm); \ + else \ + CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\ + CIRCLEQ_PREV((listelm), field) = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \ + CIRCLEQ_PREV((elm), field) = (void *)(head); \ + if (CIRCLEQ_LAST((head)) == (void *)(head)) \ + CIRCLEQ_LAST((head)) = (elm); \ + else \ + CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \ + CIRCLEQ_FIRST((head)) = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + CIRCLEQ_NEXT((elm), field) = (void *)(head); \ + CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \ + if (CIRCLEQ_FIRST((head)) == (void *)(head)) \ + CIRCLEQ_FIRST((head)) = (elm); \ + else \ + CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \ + CIRCLEQ_LAST((head)) = (elm); \ +} while (0) + +#define CIRCLEQ_LAST(head) ((head)->cqh_last) + +#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) + +#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \ + CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \ + else \ + CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \ + CIRCLEQ_PREV((elm), field); \ + if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \ + CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \ + else \ + CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \ + CIRCLEQ_NEXT((elm), field); \ +} while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* DPL_QUEUE_H */ diff --git a/porting/dpl/riot/src/config.c b/porting/dpl/riot/src/config.c new file mode 100644 index 0000000..9e4bde1 --- /dev/null +++ b/porting/dpl/riot/src/config.c @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "config/config.h" +#include +#include +#include +#include + +int conf_value_from_str(char *val_str, enum conf_type type, void *vp, int maxlen) +{ + int32_t val; + int64_t val64; + char *eptr; + + if (!val_str) { + goto err; + } + switch (type) { + case CONF_INT8: + case CONF_INT16: + case CONF_INT32: + case CONF_BOOL: + val = strtol(val_str, &eptr, 0); + if (*eptr != '\0') { + goto err; + } + if (type == CONF_BOOL) { + if (val < 0 || val > 1) { + goto err; + } + *(bool *)vp = val; + } else if (type == CONF_INT8) { + if (val < INT8_MIN || val > UINT8_MAX) { + goto err; + } + *(int8_t *)vp = val; + } else if (type == CONF_INT16) { + if (val < INT16_MIN || val > UINT16_MAX) { + goto err; + } + *(int16_t *)vp = val; + } else if (type == CONF_INT32) { + *(int32_t *)vp = val; + } + break; + case CONF_INT64: + val64 = strtoll(val_str, &eptr, 0); + if (*eptr != '\0') { + goto err; + } + *(int64_t *)vp = val64; + break; + case CONF_STRING: + val = strlen(val_str); + if (val + 1 > maxlen) { + goto err; + } + strcpy(vp, val_str); + break; + default: + goto err; + } + return 0; +err: + return EINVAL; +} -- 2.28.0