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>
This commit is contained in:
Bjorn Andersson 2018-01-30 15:55:49 -08:00
parent b4e899fffc
commit 4c693b7551
5 changed files with 136 additions and 47 deletions

95
list.h Normal file
View File

@ -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

View File

@ -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:

View File

@ -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);
}

28
qmic.c
View File

@ -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");

15
qmic.h
View File

@ -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,