1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - tools - defval
3   File:     get_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-05-13#$
14   $Rev: 5962 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include "defval.h"
18 
19 /*---------------------------------------------------------------------------*
20   Name:         get_dvalue_listptr
21 
22   Description:  Obtains a pointer to the list corresponding to the definition name.
23 
24   Arguments:    name        Variable name
25 
26   Returns:      Pointer to the definition list
27  *---------------------------------------------------------------------------*/
get_dvalue_listptr(const char * name)28 tDefineValue *get_dvalue_listptr(const char *name)
29 {
30     tDefineValue *t;
31 
32     for (t = gDefineValueTop; t; t = t->next)
33     {
34         if (!strcmp(t->name, name))
35         {
36             return t;
37         }
38     }
39     return NULL;
40 }
41 
42 /*---------------------------------------------------------------------------*
43   Name:         get_dvalue
44 
45   Description:  Gets the value of the definition name.
46                 Search the definition value list; If not there, search the environment variables
47                 If still not there, return NULL.
48 
49   Arguments:    name        Variable name
50 
51   Returns:      Pointer to the value string (No need to free)
52                 NULL: No corresponding variables
53  *---------------------------------------------------------------------------*/
get_dvalue(const char * name)54 static char *get_dvalue(const char *name)
55 {
56     tDefineValue *t = get_dvalue_listptr(name);
57 
58     return t ? t->value : getenv(name);
59 }
60 
61 /*---------------------------------------------------------------------------*
62   Name:         modify_dvalue
63 
64   Description:  Duplicates and returns the definition values after converting them using variable modifiers (:r, :t, :e, :h).
65 
66 
67   Arguments:    value     Value to modify
68                 modifier  Modifier (one of 'r', 't', 'e', 'h')
69 
70   Returns:      Pointer to the conversion value string (Must be freed)
71  *---------------------------------------------------------------------------*/
modify_dvalue(const char * value,char modifier)72 static char *modify_dvalue(const char *value, char modifier)
73 {
74     char   *value_dir;
75     char   *value_base;
76     char   *value_ext;
77     char   *modified_value;
78 
79     if (value == NULL)
80         return NULL;
81     if (modifier == '\0')
82         return StrDup(value);
83 
84     //
85     // Modification process
86     //   Divide the input value into filename elements and rebuild based on modifiers
87     //
88     UnpackFileName(value, &value_dir, &value_base, &value_ext);
89 
90     switch (modifier)
91     {
92     case 'h':                         // Directory name with final /, \ included
93         modified_value = StrDup(value_dir);
94         break;
95 
96     case 't':                         // Filename with no directory
97         modified_value = StrCatDup(value_base, value_ext);
98         break;
99 
100     case 'r':                         // Name with file extension removed from full path
101         modified_value = StrCatDup(value_dir, value_base);
102         break;
103 
104     case 'e':                         // File extension
105         modified_value = StrDup(value_ext);
106         break;
107 
108     default:                          // Unknown
109         fprintf(stderr, "Unknown modifier ':%c'... Ignored.\n", modifier);
110         modified_value = StrDup(value);
111         break;
112     }
113 
114     free(value_dir);
115     free(value_base);
116     free(value_ext);
117 
118     return modified_value;
119 }
120 
121 /*---------------------------------------------------------------------------*
122   Name:         get_modified_dvalue
123 
124   Description:  Dupicates and returns value from the definition value list, after appying conversion based on modifier (:r,:t,:e,:h).
125 
126 
127   Arguments:    name      Definition name
128 
129   Returns:      Pointer to the conversion value string (Must be freed)
130  *---------------------------------------------------------------------------*/
get_modified_dvalue(const char * name)131 static char *get_modified_dvalue(const char *name)
132 {
133     char   *name_copy = StrDup(name);
134     int     name_len = strlen(name_copy);
135     char    modifier = '\0';
136     char   *value;
137 
138     // Removes modifiers
139     if (name_len > 2 && name_copy[name_len - 2] == ':')
140     {
141         name_copy[name_len - 2] = '\0';
142         modifier = name_copy[name_len - 1];
143     }
144 
145     // Get value
146     value = modify_dvalue(get_dvalue(name_copy), modifier);
147     free(name_copy);
148 
149     DebugPrintf("REFERED(%s)=[%s]\n", name, value ? value : "(NULL)");
150     return value;
151 }
152 
153 /*---------------------------------------------------------------------------*
154   Name:         put_modified_dvalue
155 
156   Description:  Outputs a string to a file.
157                 It also expands $(XXXXX).
158 
159   Arguments:    fp   Output file name
160                 str     Character string
161 
162   Returns:      TRUE   success
163  *---------------------------------------------------------------------------*/
puts_modified_dvalue(FILE * fp,const char * str)164 BOOL puts_modified_dvalue(FILE * fp, const char *str)
165 {
166     const char *str_name;
167     int     str_name_len;
168     char   *name;
169     char   *value;
170     int     result;
171 
172     while ('\0' != *str)
173     {
174         //
175         // Search for $(XXX); If found, output corresponding value.
176         //
177         if ('$' == *str)
178         {
179             if ('$' == *(str + 1))
180             {
181                 str++;                 // Convert $$ to $.
182             }
183             else if ('(' == *(str + 1))
184             {
185                 str_name = str + 2;
186                 str_name_len = 0;
187                 while ('\0' != str_name[str_name_len])
188                 {
189                     if (')' == str_name[str_name_len])
190                     {
191                         name = StrNDup(str_name, str_name_len);
192                         value = get_modified_dvalue(name);
193                         free(name);
194 
195                         if (NULL != value)
196                         {
197                             result = fputs(value, fp);
198                             free(value);
199                             if (result == EOF)
200                             {
201                                 return FALSE;
202                             }
203                         }
204                         str = str_name + str_name_len;
205                         goto skipout;
206                     }
207                     str_name_len++;
208                 }
209             }
210         }
211 
212         //
213         // If not $(XXX), output one character at a time
214         //
215         if (EOF == fputc(*str, fp))
216         {
217             return FALSE;
218         }
219       skipout:
220         str++;
221     }
222     return TRUE;
223 }
224