To keep Interface API small, compact and readable, but versatile
[openocd/libswd.git] / src / interface / feature.c
blobf2cd5e4ce952410ecfd9fb5d8e4e1d874004e904
1 /*
2 * Copyright (C) 2012 Tomasz Boleslaw CEDRO
3 * cederom@tlen.pl, http://www.tomek.cedro.info
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <interface/feature.h>
25 #include <helper/log.h>
27 /**
28 @file oocd_feature_core Interface specific features core definitions.
29 To keep Interface API small, compact and readable, but versatile
30 and extensible at the same time 'Interface Features' are introduced.
31 Interface Features is a dynamic list of user definable driver extensions
32 that can provide additional functionalities to the interface driver.
33 Intelligent drivers can expose their hardware specific operations this way,
34 while generic drivers can get additional applications with use of external
35 libraries that will generate additional features (ie. LibSWD for SWD support).
36 Interface Features API was invented and introduced in 2012 by Tomasz Boleslaw
37 CEDRO (http://www.tomek.cedro.info) as a part of generic SWD implementation
38 for OpenOCD with use of LibSWD (http://libswd.sf.net).
41 /** Add feature new_feature to existing list of features. */
42 int oocd_feature_add(oocd_feature_t *features, oocd_feature_t *new_feature)
44 oocd_feature_t *last_feature;
46 if (features == NULL) {
47 LOG_ERROR("Invalid features list selected (no features)!");
48 return ERROR_FAIL;
51 if (new_feature == NULL || new_feature->name == NULL || new_feature->body == NULL) {
52 LOG_ERROR("Cannot add this invalid feature!");
53 return ERROR_FAIL;
56 if (oocd_feature_find(features, new_feature->name) != NULL) {
57 LOG_ERROR("Feature %s already on the list!", new_feature->name);
58 return ERROR_FAIL;
61 for (last_feature = features; last_feature->next != NULL; last_feature = last_feature->next)
63 new_feature->next = NULL;
64 last_feature->next = new_feature;
66 return ERROR_OK;
69 /** Add new_feature or replace existing feature on the list. */
70 int oocd_feature_update(oocd_feature_t *features, oocd_feature_t *new_feature)
72 oocd_feature_t *feature = features;
74 if (features == NULL) {
75 LOG_ERROR("Invalid features list selected (no features)!");
76 return ERROR_FAIL;
79 if (new_feature == NULL || new_feature->name == NULL || new_feature->body == NULL) {
80 LOG_ERROR("Cannot add this invalid feature!");
81 return ERROR_FAIL;
84 if (oocd_feature_find(features, new_feature->name) == NULL) {
85 for (feature = features; feature->next != NULL; feature = feature->next)
87 new_feature->next = NULL;
88 feature->next = new_feature;
89 return ERROR_OK;
90 } else {
91 feature = features;
92 if (feature->next == NULL)
93 if (strncmp(new_feature->name, feature->name, OOCD_FEATURE_NAME_MAXLEN) == 0) {
94 feature = new_feature;
95 return ERROR_OK;
97 while (feature != NULL) {
98 if (feature->next == NULL)
99 break;
100 if (strncmp(new_feature->name, feature->next->name, OOCD_FEATURE_NAME_MAXLEN) == 0) {
101 if (feature->next->next == NULL)
102 feature->next = new_feature;
103 else {
104 new_feature->next = feature->next->next;
105 feature->next = new_feature;
107 return ERROR_OK;
109 feature = feature->next;
112 return ERROR_FAIL;
115 /** Remove feature by given name from a features list. */
116 int oocd_feature_del(oocd_feature_t *features, char *name)
118 oocd_feature_t *feature = features;
120 if (features == NULL) {
121 LOG_ERROR("Invalid features list selected (no features)!");
122 return ERROR_FAIL;
125 if (feature->next == NULL) {
126 if (strncmp(name, feature->name, OOCD_FEATURE_NAME_MAXLEN) == 0) {
127 features = NULL;
128 LOG_DEBUG("Removed feature: %s", name);
129 return ERROR_OK;
133 while (feature != NULL) {
134 if (feature->next == NULL)
135 break;
136 if (strncmp(name, feature->next->name, OOCD_FEATURE_NAME_MAXLEN) == 0) {
137 if (feature->next->next == NULL)
138 feature->next = NULL;
139 else
140 feature->next = feature->next->next;
141 LOG_DEBUG("Removed feature: %s", name);
142 return ERROR_OK;
144 feature = feature->next;
146 return ERROR_OK;
149 /** Find feature by a name from list of features. */
150 oocd_feature_t *oocd_feature_find(oocd_feature_t *features, char *name)
152 oocd_feature_t *feature = features;
154 if (features == NULL) {
155 LOG_ERROR("Invalid features list selected (no features)!");
156 return NULL;
159 while (feature != NULL) {
160 if (strncmp(name, feature->name, OOCD_FEATURE_NAME_MAXLEN) == 0)
161 return feature;
162 feature = feature->next;
164 return NULL;