1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - tools - defval
3   File:     set_defval.c
4 
5   Copyright 2005-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include "defval.h"
18 
19 static BOOL add_dvalue(const char *name, const char *value);
20 static char *clip_whitespace(char *str);
21 
22 
23 //---------------------------------------------------------------------------
24 //  List that maintains defined values
25 //---------------------------------------------------------------------------
26 tDefineValue *gDefineValueTop = NULL;
27 
28 /*---------------------------------------------------------------------------*
29   Name:         add_dvalue
30 
31   Description:  Adds a new value to the defined value list.
32 
33   Arguments:    name        Variable name
34                 value   Variable's value
35 
36                 If name  is NULL or "", then do nothing and end (Return FALSE)
37                 If value is NULL, it is treated as being defined as "".
38 
39   Returns:      TRUE   Added a new one
40                 FALSE   Value with the same name is already stored (Overwritten by the new one)
41  *---------------------------------------------------------------------------*/
add_dvalue(const char * name,const char * value)42 static BOOL add_dvalue(const char *name, const char *value)
43 {
44     tDefineValue *t;
45 
46     //
47     // Handling when NULL
48     //   If name is NULL or "", then do nothing and end (Return TRUE)
49     //   If value is NULL, it is treated as being defined as "".
50     //
51     if (name == NULL || name[0] == '\0')
52     {
53         return TRUE;
54     }
55     if (value == NULL)
56     {
57         value = (const char *)"";
58     }
59 
60     DebugPrintf("DEFINE:$(%s)=\"%s\"\n", name, value);
61 
62     // If a definition name with the same name exists, replace it with the new value.
63     if (NULL != (t = get_dvalue_listptr(name)))
64     {
65         if (t->value)
66             free(t->value);
67         t->value = StrDup(value);
68         return FALSE;
69     }
70 
71     // If it is a new definition name, expand the list and register it.
72     t = Calloc(sizeof(tDefineValue));
73     t->name = StrDup(name);
74     t->value = StrDup(value);
75     t->next = gDefineValueTop;
76     gDefineValueTop = t;
77 
78     return TRUE;
79 }
80 
81 /*---------------------------------------------------------------------------*
82   Name:         add_dvalue_by_equality
83 
84   Description:  Adds a new value in the form of an equation to the definition list.
85 
86   Arguments:    equality:  Equation "DEFINE=VALUE"
87 
88                 If equality is NULL or "", does nothing.
89 
90   Returns:      TRUE   Added a new one
91                 FALSE   Value with the same name is already stored (Overwritten by the new one)
92  *---------------------------------------------------------------------------*/
add_dvalue_by_equality(const char * equality)93 BOOL add_dvalue_by_equality(const char *equality)
94 {
95     char   *name;
96     char   *value;
97     char   *scratch;
98     BOOL    result;
99 
100     //
101     //  Copy equation to changeable region, divide into name and value before and after '='
102     //
103     scratch = StrDup(equality);
104     name = scratch;
105     value = scratch;
106     while ('\0' != *value)
107     {
108         if ('=' == *value)
109         {
110             *value = '\0';             // Divide by entering '\0' at the position of '='
111             value++;
112             break;
113         }
114         value++;
115     }
116     name = clip_whitespace(name);      // Delete white space before and after.
117     value = clip_whitespace(value);
118 
119     //
120     //  Register the value
121     //
122     result = add_dvalue(name, value);
123     free(scratch);
124 
125     return result;
126 }
127 
128 /*---------------------------------------------------------------------------*
129   Name:         add_dvalue_from_file
130 
131   Description:  Adds equation inside the file to the definition value list.
132 
133   Arguments:    filename The filename
134                 "DEFINE=VALUE" list
135 
136   Returns:      TRUE   Successful
137                 FALSE   Value with the same name is already stored (Overwritten by the new one)
138  *---------------------------------------------------------------------------*/
add_dvalue_from_file(const char * filename)139 BOOL add_dvalue_from_file(const char *filename)
140 {
141     FILE   *fp;
142     char   *buffer;
143     int     buffer_size;
144     int     line_num;
145 
146     if (filename[0] == '-' && filename[1] == '\0')
147     {
148         fp = stdin;
149     }
150     else if (NULL == (fp = fopen(filename, "r")))
151     {
152         fprintf(stderr, "Cannot open file \"%s\".\n", filename);
153         return FALSE;
154     }
155 
156     //
157     // Read the file line by line and register the variables
158     //
159     buffer = NULL;
160     buffer_size = line_num = 0;
161     while (NULL != Fgets(&buffer, &buffer_size, fp))
162     {
163         line_num++;
164         if (!add_dvalue_by_equality(buffer))
165         {
166             fprintf(stderr, "line %d: found same entry: %s\n", line_num, buffer);
167         }
168     }
169 
170     if (fp != stdin)
171         fclose(fp);
172 
173     return TRUE;
174 }
175 
176 /*---------------------------------------------------------------------------*
177   Name:         chip_whitespace
178 
179   Description:  Delete white space before and after character string.
180 
181   Arguments:    str    Beginning of the string to process
182 
183                 The contents of this str will be overwritten, so it does not work with a const area
184 
185   Returns:      The new starting position
186  *---------------------------------------------------------------------------*/
clip_whitespace(char * str)187 static char *clip_whitespace(char *str)
188 {
189     int     n;
190 
191     // Fill the trailing blank space with '\0'
192     for (n = strlen(str) - 1; n >= 0; n--)
193     {
194         if (!isspace(str[n]))
195         {
196             str[n + 1] = '\0';
197             break;
198         }
199     }
200 
201     // Skip leading blank space and return a pointer to the beginning of the string
202     for (n = 0; str[n] != '\0'; n++)
203     {
204         if (!isspace(str[n]))
205         {
206             break;
207         }
208     }
209     return str + n;
210 }
211