1 /*****************************************************************************/
5 /* Command line attributes */
9 /* (C) 2012, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
50 /*****************************************************************************/
52 /*****************************************************************************/
56 static int IsNumber (const char* Value)
57 /* Check if Value is an integer number */
59 if (*Value == '-' || *Value == '+') {
62 while (IsDigit (*Value)) {
65 return (*Value == '\0');
70 Attr* NewAttr (const char* Name, const char* Value)
71 /* Create a new attribute */
73 /* Determine the length of Value */
74 unsigned Len = strlen (Value);
77 Attr* A = xmalloc (sizeof (Attr) + Len);
79 /* Initialize the fields */
80 A->Flags = IsNumber (Value)? afInt : afNone;
81 A->Name = xstrdup (Name);
82 memcpy (A->Value, Value, Len + 1);
84 /* Return the new struct */
90 void DumpAttrColl (const Collection* C)
91 /* Dump a collection of attribute/value pairs for debugging */
94 for (I = 0; I < CollCount (C); ++I) {
95 const Attr* A = CollConstAt (C, I);
96 printf ("%s=%s\n", A->Name, A->Value);
102 int FindAttr (const Collection* C, const char* Name, unsigned* Index)
103 /* Search for an attribute with the given name in the collection. If it is
104 * found, the function returns true and Index contains the index of the
105 * entry. If Name isn't found, the function returns false and Index
106 * will contain the insert position.
109 /* Do a binary search */
111 int Hi = (int) CollCount (C) - 1;
115 int Cur = (Lo + Hi) / 2;
118 const Attr* A = CollAt (C, Cur);
121 int Res = strcmp (A->Name, Name);
126 } else if (Res > 0) {
135 /* Pass back the insert position */
142 void AddAttr (Collection* C, const char* Name, const char* Value)
143 /* Add an attribute to an alphabetically sorted attribute collection */
145 /* Create a new attribute entry */
146 Attr* A = NewAttr (Name, Value);
148 /* Search for the attribute. If it is there, we have a duplicate, otherwise
149 * we have the insert position.
152 if (FindAttr (C, Name, &Index)) {
153 Error ("Duplicate command line attribute `%s'", Name);
156 /* Insert the attribute */
157 CollInsert (C, A, Index);
162 void SplitAddAttr (Collection* C, const char* Combined, const char* Name)
163 /* Split a combined name/value pair and add it as an attribute to C. Some
164 * attributes may not need a name. If the name is missing, use Name. If
165 * Name is NULL, terminate with an error.
168 /* Name and value are separated by an equal sign */
169 const char* Pos = strchr (Combined, '=');
171 /* Combined is actually a value */
173 Error ("Command line attribute `%s' doesn't contain a name", Name);
175 AddAttr (C, Name, Combined);
177 /* Must split name and value */
178 StrBuf N = AUTO_STRBUF_INITIALIZER;
179 SB_CopyBuf (&N, Combined, Pos - Combined);
182 /* Add the attribute */
183 AddAttr (C, SB_GetConstBuf (&N), Pos+1);