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 <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "list.h"
#include "qmic.h" #include "qmic.h"
static const char *sz_simple_types[] = { static const char *sz_simple_types[] = {
@ -19,7 +21,7 @@ struct qmi_message_member {
bool required; bool required;
unsigned array; unsigned array;
struct qmi_message_member *next; struct list_head node;
}; };
struct qmi_message { struct qmi_message {
@ -27,12 +29,12 @@ struct qmi_message {
const char *name; const char *name;
unsigned msg_id; 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) 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 = malloc(sizeof(struct qmi_message));
qm->name = msg_id_tok.str; qm->name = msg_id_tok.str;
qm->type = message_type; qm->type = message_type;
list_init(&qm->members);
while (!token_accept('}', NULL)) { while (!token_accept('}', NULL)) {
array = 0; array = 0;
@ -89,7 +92,7 @@ void qmi_message_parse(enum message_type message_type)
qmm->required = required; qmm->required = required;
qmm->array = array; qmm->array = array;
LIST_ADD(qm->members, qmm); list_add(&qm->members, &qmm->node);
} }
if (token_accept('=', NULL)) { if (token_accept('=', NULL)) {
@ -100,7 +103,7 @@ void qmi_message_parse(enum message_type message_type)
token_expect(';', NULL); token_expect(';', NULL);
LIST_ADD(qmi_messages, qm); list_add(&qmi_messages, &qm->node);
} }
static void qmi_message_emit_message_type(FILE *fp, 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_member *qmm;
struct qmi_message *qm; 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); 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) { switch (qmm->type) {
case TYPE_U8: case TYPE_U8:
case TYPE_U16: case TYPE_U16:
@ -309,6 +312,7 @@ void qmi_message_source(FILE *fp, const char *package)
break; break;
}; };
} }
}
} }
void qmi_message_header(FILE *fp, const char *package) void qmi_message_header(FILE *fp, const char *package)
@ -316,15 +320,15 @@ void qmi_message_header(FILE *fp, const char *package)
struct qmi_message_member *qmm; struct qmi_message_member *qmm;
struct qmi_message *qm; 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); qmi_message_emit_message_type(fp, package, qm->name);
fprintf(fp, "\n"); 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); 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) { switch (qmm->type) {
case TYPE_U8: case TYPE_U8:
case TYPE_U16: case TYPE_U16:

View File

@ -1,5 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "list.h"
#include "qmic.h" #include "qmic.h"
static const char *sz_simple_types[] = { static const char *sz_simple_types[] = {
@ -14,18 +16,18 @@ struct qmi_struct_member {
const char *name; const char *name;
int type; int type;
struct qmi_struct_member *next; struct list_head node;
}; };
struct qmi_struct { struct qmi_struct {
const char *name; 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) void qmi_struct_parse(void)
{ {
@ -40,6 +42,7 @@ void qmi_struct_parse(void)
qs = malloc(sizeof(struct qmi_struct)); qs = malloc(sizeof(struct qmi_struct));
qs->name = struct_id_tok.str; qs->name = struct_id_tok.str;
list_init(&qs->members);
while (token_accept(TOK_TYPE, &type_tok)) { while (token_accept(TOK_TYPE, &type_tok)) {
token_expect(TOK_ID, &id_tok); token_expect(TOK_ID, &id_tok);
@ -49,13 +52,13 @@ void qmi_struct_parse(void)
qsm->name = id_tok.str; qsm->name = id_tok.str;
qsm->type = type_tok.num; qsm->type = type_tok.num;
LIST_ADD(qs->members, qsm); list_add(&qs->members, &qsm->node);
} }
token_expect('}', NULL); token_expect('}', NULL);
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); 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_member *qsm;
struct qmi_struct *qs; 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", fprintf(fp, "struct %s_%s {\n",
package, qs->name); 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", fprintf(fp, "\t%s %s;\n",
sz_simple_types[qsm->type], qsm->name); sz_simple_types[qsm->type], qsm->name);
} }

26
qmic.c
View File

@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "list.h"
#include "qmic.h" #include "qmic.h"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
@ -66,10 +67,10 @@ struct symbol {
int type; int type;
struct qmi_struct *qmi_struct; 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, ...) 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 = malloc(sizeof(struct symbol));
sym->token = token; sym->token = token;
sym->name = name; sym->name = name;
sym->next = NULL;
switch (token) { switch (token) {
case TOK_MESSAGE: case TOK_MESSAGE:
@ -94,7 +94,7 @@ void symbol_add(const char *name, int token, ...)
break; break;
} }
LIST_ADD(symbols, sym); list_add(&symbols, &sym->node);
va_end(ap); va_end(ap);
} }
@ -108,6 +108,8 @@ static struct token yylex()
int base; int base;
int ch; int ch;
list_for_each_entry(sym, &symbols, node);
while ((ch = input()) && isspace(ch)) while ((ch = input()) && isspace(ch))
; ;
@ -120,16 +122,15 @@ static struct token yylex()
*p = '\0'; *p = '\0';
token.str = strdup(buf); 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) { if (strcmp(buf, sym->name) == 0) {
token.id = sym->token; token.id = sym->token;
token.num = sym->type; token.num = sym->type;
token.qmi_struct = sym->qmi_struct; token.qmi_struct = sym->qmi_struct;
break; return token;
} }
} }
if (!sym)
token.id = TOK_ID; token.id = TOK_ID;
return token; return token;
@ -235,10 +236,10 @@ struct qmi_const {
const char *name; const char *name;
unsigned value; 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() static void qmi_const_parse()
{ {
@ -254,17 +255,18 @@ static void qmi_const_parse()
qc = malloc(sizeof(struct qmi_const)); qc = malloc(sizeof(struct qmi_const));
qc->name = id_tok.str; qc->name = id_tok.str;
qc->value = num_tok.num; qc->value = num_tok.num;
LIST_ADD(qmi_consts, qc);
list_add(&qmi_consts, &qc->node);
} }
static void qmi_const_header(FILE *fp) static void qmi_const_header(FILE *fp)
{ {
struct qmi_const *qc; struct qmi_const *qc;
if (!qmi_consts.head) if (list_empty(&qmi_consts))
return; 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, "#define %s %d\n", qc->name, qc->value);
fprintf(fp, "\n"); fprintf(fp, "\n");

15
qmic.h
View File

@ -3,21 +3,6 @@
#include <stdbool.h> #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 { enum {
TOK_CONST = 256, TOK_CONST = 256,
TOK_ID, TOK_ID,