1 /**
2  * @file
3  * Handling of personal config ('my' variables)
4  *
5  * @authors
6  * Copyright (C) 2018 Richard Russon <rich@flatcap.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /**
24  * @page neo_myvar Handling of personal config ('my' variables)
25  *
26  * Handling of personal config ('my' variables)
27  */
28 
29 #include "config.h"
30 #include <stddef.h>
31 #include "mutt/lib.h"
32 #include "myvar.h"
33 
34 struct MyVarList MyVars = TAILQ_HEAD_INITIALIZER(MyVars);
35 
36 /**
37  * myvar_new - Create a new MyVar
38  * @param name  Variable name
39  * @param value Variable value
40  * @retval ptr New MyVar
41  *
42  * @note The name and value will be copied.
43  */
myvar_new(const char * name,const char * value)44 static struct MyVar *myvar_new(const char *name, const char *value)
45 {
46   struct MyVar *myv = mutt_mem_calloc(1, sizeof(struct MyVar));
47   myv->name = mutt_str_dup(name);
48   myv->value = mutt_str_dup(value);
49   return myv;
50 }
51 
52 /**
53  * myvar_free - Free a MyVar
54  * @param ptr MyVar to free
55  */
myvar_free(struct MyVar ** ptr)56 static void myvar_free(struct MyVar **ptr)
57 {
58   if (!ptr || !*ptr)
59     return;
60 
61   struct MyVar *myv = *ptr;
62   FREE(&myv->name);
63   FREE(&myv->value);
64   FREE(ptr);
65 }
66 
67 /**
68  * myvar_find - Locate a "my_" variable
69  * @param var Variable name
70  * @retval ptr  Success, variable exists
71  * @retval NULL Error, variable doesn't exist
72  */
myvar_find(const char * var)73 static struct MyVar *myvar_find(const char *var)
74 {
75   struct MyVar *myv = NULL;
76 
77   TAILQ_FOREACH(myv, &MyVars, entries)
78   {
79     if (mutt_str_equal(myv->name, var))
80       return myv;
81   }
82 
83   return NULL;
84 }
85 
86 /**
87  * myvar_get - Get the value of a "my_" variable
88  * @param var Variable name
89  * @retval ptr  Success, value of variable
90  * @retval NULL Error, variable doesn't exist
91  */
myvar_get(const char * var)92 const char *myvar_get(const char *var)
93 {
94   struct MyVar *myv = myvar_find(var);
95 
96   if (myv)
97   {
98     return NONULL(myv->value);
99   }
100 
101   return NULL;
102 }
103 
104 /**
105  * myvar_set - Set the value of a "my_" variable
106  * @param var Variable name
107  * @param val Value to set
108  */
myvar_set(const char * var,const char * val)109 void myvar_set(const char *var, const char *val)
110 {
111   struct MyVar *myv = myvar_find(var);
112 
113   if (myv)
114   {
115     mutt_str_replace(&myv->value, val);
116     return;
117   }
118 
119   myv = myvar_new(var, val);
120   TAILQ_INSERT_TAIL(&MyVars, myv, entries);
121 }
122 
123 /**
124  * myvar_append - Append to the value of a "my_" variable
125  * @param var Variable name
126  * @param val Value to append
127  */
myvar_append(const char * var,const char * val)128 void myvar_append(const char *var, const char *val)
129 {
130   struct MyVar *myv = myvar_find(var);
131 
132   if (myv)
133   {
134     mutt_str_append_item(&myv->value, val, '\0');
135     return;
136   }
137 
138   myv = myvar_new(var, val);
139   TAILQ_INSERT_TAIL(&MyVars, myv, entries);
140 }
141 
142 /**
143  * myvar_del - Unset the value of a "my_" variable
144  * @param var Variable name
145  */
myvar_del(const char * var)146 void myvar_del(const char *var)
147 {
148   struct MyVar *myv = myvar_find(var);
149 
150   if (myv)
151   {
152     TAILQ_REMOVE(&MyVars, myv, entries);
153     myvar_free(&myv);
154   }
155 }
156 
157 /**
158  * myvarlist_free - Free a List of MyVars
159  * @param list List of MyVars
160  */
myvarlist_free(struct MyVarList * list)161 void myvarlist_free(struct MyVarList *list)
162 {
163   if (!list)
164     return;
165 
166   struct MyVar *myv = NULL;
167   struct MyVar *tmp = NULL;
168   TAILQ_FOREACH_SAFE(myv, list, entries, tmp)
169   {
170     TAILQ_REMOVE(list, myv, entries);
171     myvar_free(&myv);
172   }
173 }
174