summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2018-01-30 15:55:49 -0800
committerBjorn Andersson <bjorn.andersson@linaro.org>2018-01-30 15:55:49 -0800
commit4c693b75514c3ae5fbe68d373911ad5825b5a81c (patch)
tree1c49ef6dfdcaa46b3edfb335ea196a904f645f39
parentb4e899fffcf25c28a88317c4472d06b37f4018c0 (diff)
qmic: Adopt common list implementation
Use the list implementation from other projects instead of rolling custom list operations throughout the codebase. Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r--list.h95
-rw-r--r--qmi_message.c26
-rw-r--r--qmi_struct.c19
-rw-r--r--qmic.c28
-rw-r--r--qmic.h15
5 files changed, 136 insertions, 47 deletions
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..1ef5083
--- /dev/null
+++ b/list.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Linaro Ltd.
+ * 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.
+ *
+ * 3. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+#ifndef __LIST_H__
+#define __LIST_H__
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member)*__mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); \
+ })
+
+struct list_head {
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+#define LIST_INIT(list) { &(list), &(list) }
+
+static inline void list_init(struct list_head *list)
+{
+ list->prev = list->next = list;
+}
+
+static inline bool list_empty(struct list_head *list)
+{
+ return list->next == list;
+}
+
+static inline void list_add(struct list_head *list, struct list_head *item)
+{
+ struct list_head *prev = list->prev;
+
+ item->next = list;
+ item->prev = prev;
+
+ prev->next = list->prev = item;
+}
+
+static inline void list_del(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+}
+
+#define list_for_each(item, list) \
+ for (item = (list)->next; item != list; item = item->next)
+
+#define list_for_each_safe(item, next, list) \
+ for (item = (list)->next, next = item->next; item != list; item = next, next = item->next)
+
+#define list_entry(item, type, member) \
+ container_of(item, type, member)
+
+#define list_entry_first(list, type, member) \
+ container_of((list)->next, type, member)
+
+#define list_entry_next(item, member) \
+ container_of((item)->member.next, typeof(*(item)), member)
+
+#define list_for_each_entry(item, list, member) \
+ for (item = list_entry_first(list, typeof(*(item)), member); \
+ &item->member != list; \
+ item = list_entry_next(item, member))
+
+#endif
diff --git a/qmi_message.c b/qmi_message.c
index c1dbfd7..a306baf 100644
--- a/qmi_message.c
+++ b/qmi_message.c
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+
+#include "list.h"
#include "qmic.h"
static const char *sz_simple_types[] = {
@@ -19,7 +21,7 @@ struct qmi_message_member {
bool required;
unsigned array;
- struct qmi_message_member *next;
+ struct list_head node;
};
struct qmi_message {
@@ -27,12 +29,12 @@ struct qmi_message {
const char *name;
unsigned msg_id;
- struct qmi_message *next;
+ struct list_head node;
- LIST_HEAD(qmi_message_member, members);
+ struct list_head members;
};
-LIST_HEAD(qmi_message, qmi_messages);
+static struct list_head qmi_messages = LIST_INIT(qmi_messages);
void qmi_message_parse(enum message_type message_type)
{
@@ -51,6 +53,7 @@ void qmi_message_parse(enum message_type message_type)
qm = malloc(sizeof(struct qmi_message));
qm->name = msg_id_tok.str;
qm->type = message_type;
+ list_init(&qm->members);
while (!token_accept('}', NULL)) {
array = 0;
@@ -89,7 +92,7 @@ void qmi_message_parse(enum message_type message_type)
qmm->required = required;
qmm->array = array;
- LIST_ADD(qm->members, qmm);
+ list_add(&qm->members, &qmm->node);
}
if (token_accept('=', NULL)) {
@@ -100,7 +103,7 @@ void qmi_message_parse(enum message_type message_type)
token_expect(';', NULL);
- LIST_ADD(qmi_messages, qm);
+ list_add(&qmi_messages, &qm->node);
}
static void qmi_message_emit_message_type(FILE *fp,
@@ -290,10 +293,10 @@ void qmi_message_source(FILE *fp, const char *package)
struct qmi_message_member *qmm;
struct qmi_message *qm;
- for (qm = qmi_messages.head; qm; qm = qm->next) {
+ list_for_each_entry(qm, &qmi_messages, node) {
qmi_message_emit_message(fp, package, qm);
- for (qmm = qm->members.head; qmm; qmm = qmm->next)
+ list_for_each_entry(qmm, &qm->members, node) {
switch (qmm->type) {
case TYPE_U8:
case TYPE_U16:
@@ -308,6 +311,7 @@ void qmi_message_source(FILE *fp, const char *package)
qmi_struct_emit_accessors(fp, package, qm->name, qmm->name, qmm->id, qmm->array, qmm->qmi_struct);
break;
};
+ }
}
}
@@ -316,15 +320,15 @@ void qmi_message_header(FILE *fp, const char *package)
struct qmi_message_member *qmm;
struct qmi_message *qm;
- for (qm = qmi_messages.head; qm; qm = qm->next)
+ list_for_each_entry(qm, &qmi_messages, node)
qmi_message_emit_message_type(fp, package, qm->name);
fprintf(fp, "\n");
- for (qm = qmi_messages.head; qm; qm = qm->next) {
+ list_for_each_entry(qm, &qmi_messages, node) {
qmi_message_emit_message_prototype(fp, package, qm->name);
- for (qmm = qm->members.head; qmm; qmm = qmm->next) {
+ list_for_each_entry(qmm, &qm->members, node) {
switch (qmm->type) {
case TYPE_U8:
case TYPE_U16:
diff --git a/qmi_struct.c b/qmi_struct.c
index ffa9dbf..96405d2 100644
--- a/qmi_struct.c
+++ b/qmi_struct.c
@@ -1,5 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
+
+#include "list.h"
#include "qmic.h"
static const char *sz_simple_types[] = {
@@ -14,18 +16,18 @@ struct qmi_struct_member {
const char *name;
int type;
- struct qmi_struct_member *next;
+ struct list_head node;
};
struct qmi_struct {
const char *name;
- struct qmi_struct *next;
+ struct list_head node;
- LIST_HEAD(qmi_struct_member, members);
+ struct list_head members;
};
-LIST_HEAD(qmi_struct, qmi_structs);
+static struct list_head qmi_structs = LIST_INIT(qmi_structs);
void qmi_struct_parse(void)
{
@@ -40,6 +42,7 @@ void qmi_struct_parse(void)
qs = malloc(sizeof(struct qmi_struct));
qs->name = struct_id_tok.str;
+ list_init(&qs->members);
while (token_accept(TOK_TYPE, &type_tok)) {
token_expect(TOK_ID, &id_tok);
@@ -49,13 +52,13 @@ void qmi_struct_parse(void)
qsm->name = id_tok.str;
qsm->type = type_tok.num;
- LIST_ADD(qs->members, qsm);
+ list_add(&qs->members, &qsm->node);
}
token_expect('}', NULL);
token_expect(';', NULL);
- LIST_ADD(qmi_structs, qs);
+ list_add(&qmi_structs, &qs->node);
symbol_add(qs->name, TOK_TYPE, TYPE_STRUCT, qs);
}
@@ -65,10 +68,10 @@ void qmi_struct_header(FILE *fp, const char *package)
struct qmi_struct_member *qsm;
struct qmi_struct *qs;
- for (qs = qmi_structs.head; qs; qs = qs->next) {
+ list_for_each_entry(qs, &qmi_structs, node) {
fprintf(fp, "struct %s_%s {\n",
package, qs->name);
- for (qsm = qs->members.head; qsm; qsm = qsm->next) {
+ list_for_each_entry(qsm, &qs->members, node) {
fprintf(fp, "\t%s %s;\n",
sz_simple_types[qsm->type], qsm->name);
}
diff --git a/qmic.c b/qmic.c
index 857c4e1..ba74298 100644
--- a/qmic.c
+++ b/qmic.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include "list.h"
#include "qmic.h"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
@@ -66,10 +67,10 @@ struct symbol {
int type;
struct qmi_struct *qmi_struct;
- struct symbol *next;
+ struct list_head node;
};
-LIST_HEAD(symbol, symbols);
+static struct list_head symbols = LIST_INIT(symbols);
void symbol_add(const char *name, int token, ...)
{
@@ -81,7 +82,6 @@ void symbol_add(const char *name, int token, ...)
sym = malloc(sizeof(struct symbol));
sym->token = token;
sym->name = name;
- sym->next = NULL;
switch (token) {
case TOK_MESSAGE:
@@ -94,7 +94,7 @@ void symbol_add(const char *name, int token, ...)
break;
}
- LIST_ADD(symbols, sym);
+ list_add(&symbols, &sym->node);
va_end(ap);
}
@@ -108,6 +108,8 @@ static struct token yylex()
int base;
int ch;
+ list_for_each_entry(sym, &symbols, node);
+
while ((ch = input()) && isspace(ch))
;
@@ -120,17 +122,16 @@ static struct token yylex()
*p = '\0';
token.str = strdup(buf);
- for (sym = symbols.head; sym; sym = sym->next) {
+ list_for_each_entry(sym, &symbols, node) {
if (strcmp(buf, sym->name) == 0) {
token.id = sym->token;
token.num = sym->type;
token.qmi_struct = sym->qmi_struct;
- break;
+ return token;
}
}
- if (!sym)
- token.id = TOK_ID;
+ token.id = TOK_ID;
return token;
} else if (isdigit(ch)) {
@@ -235,10 +236,10 @@ struct qmi_const {
const char *name;
unsigned value;
- struct qmi_const *next;
+ struct list_head node;
};
-LIST_HEAD(qmi_const, qmi_consts);
+static struct list_head qmi_consts = LIST_INIT(qmi_consts);
static void qmi_const_parse()
{
@@ -254,17 +255,18 @@ static void qmi_const_parse()
qc = malloc(sizeof(struct qmi_const));
qc->name = id_tok.str;
qc->value = num_tok.num;
- LIST_ADD(qmi_consts, qc);
+
+ list_add(&qmi_consts, &qc->node);
}
static void qmi_const_header(FILE *fp)
{
struct qmi_const *qc;
- if (!qmi_consts.head)
+ if (list_empty(&qmi_consts))
return;
- for (qc = qmi_consts.head; qc; qc = qc->next)
+ list_for_each_entry(qc, &qmi_consts, node)
fprintf(fp, "#define %s %d\n", qc->name, qc->value);
fprintf(fp, "\n");
diff --git a/qmic.h b/qmic.h
index 1e81f50..202d0da 100644
--- a/qmic.h
+++ b/qmic.h
@@ -3,21 +3,6 @@
#include <stdbool.h>
-#define LIST_HEAD(type, name) \
-struct { \
- struct type *head; \
- struct type *tail; \
-} name;
-
-#define LIST_ADD(list, elem) \
- if (list.tail) { \
- list.tail->next = elem; \
- list.tail = elem; \
- } else { \
- list.tail = elem; \
- list.head = elem; \
- }
-
enum {
TOK_CONST = 256,
TOK_ID,