41 #include "switchtec/ini.h"
43 void handle_section_state(
char current_char,
char *current_section,
int *position) {
44 current_section[(*position)++] = current_char;
47 void handle_name_state(
char current_char,
char *current_name,
int *position) {
48 current_name[(*position)++] = current_char;
51 void handle_value_state(
char current_char,
char *returned_string,
int *position,
int *valueStartWithDoubleQuote) {
52 if (*position == 0 && current_char ==
'"') {
53 *valueStartWithDoubleQuote = 1;
55 returned_string[(*position)++] = current_char;
58 void finalize_section_state(
char *current_section,
int *position) {
59 current_section[(*position)++] =
'\0';
62 void finalize_name_state(
char *current_name,
int *position) {
63 current_name[(*position)++] =
'\0';
66 void finalize_value_state(
char *returned_string,
int *position,
int *valueStartWithDoubleQuote) {
67 if (*position > 0 && returned_string[*position - 1] ==
'"') {
68 if (*valueStartWithDoubleQuote != 0) {
70 for (
int copy = 0; copy < *position - 1; copy++) {
71 returned_string[copy] = returned_string[copy + 1];
76 returned_string[(*position)++] =
'\0';
79 void handle_state_transition(
char current_char,
enum INI_STATE *state,
enum INI_STATE *new_state,
char *current_section,
char *current_name,
char *returned_string,
int *position,
int *valueStartWithDoubleQuote,
int nSize)
90 if (*state == SECTION)
112 handle_section_state(current_char, current_section, position);
115 handle_name_state(current_char, current_name, position);
118 handle_value_state(current_char, returned_string, position, valueStartWithDoubleQuote);
124 handle_name_state(current_char, current_name, position);
132 if (*position > nSize - 2)
134 *position = nSize - 2;
138 if (*position > MAX_LENGTH - 2)
140 *position = MAX_LENGTH - 2;
148 int get_key_list(
const char *section,
const char *name,
const char *defaultValue,
char *KeyList,
int nSize, FILE *fp) {
149 char current_section[MAX_LENGTH];
150 char current_name[MAX_LENGTH];
151 char returned_string[KEY_BUF_SIZE];
155 strncpy(returned_string, defaultValue, nSize);
156 returned_string[nSize - 1] =
'\0';
157 return strnlen(returned_string, nSize - 1);
159 enum INI_STATE state = NONE;
160 enum INI_STATE new_state = NONE;
162 int valueStartWithDoubleQuote = 0;
168 fseek(fp, 0, SEEK_END);
169 int size = ftell(fp);
170 fseek(fp, 0, SEEK_SET);
173 size_t readed = fread(¤t_char, 1, 1, fp);
176 handle_state_transition(current_char, &state, &new_state, current_section, current_name, returned_string, &position, &valueStartWithDoubleQuote, nSize);
178 if (new_state != state)
183 finalize_section_state(current_section, &position);
186 finalize_name_state(current_name, &position);
189 finalize_value_state(returned_string, &position, &valueStartWithDoubleQuote);
191 if (position > 0 && returned_string[position - 1] ==
'"') {
193 if (valueStartWithDoubleQuote != 0) {
195 for (
int copy = 0; copy < position - 1; copy++)
197 returned_string[copy] = returned_string[copy + 1];
202 returned_string[position++] =
'\0';
204 if(strncmp(current_section, section, MAX_LENGTH) == 0)
206 if(strncmp(current_name, name, MAX_LENGTH) == 0) {
207 memcpy(&KeyList[0], returned_string, strlen(returned_string));
208 pos = pos + strlen(returned_string);
209 KeyList[pos++] =
'\0';
211 return strnlen(returned_string, nSize - 1);
213 else if (strncmp(name,
"NULL", MAX_LENGTH) == 0) {
214 memcpy(&KeyList[pos], current_name, strlen(current_name));
215 pos = pos + strlen(current_name);
217 KeyList[pos++] =
'\0';
218 KeyList[pos++] =
'=';
220 memcpy(&KeyList[pos++], returned_string, strlen(returned_string));
221 KeyList[pos++] =
'\0';
228 memcpy(KeyList, defaultValue, nSize);
229 KeyList[nSize - 1] =
'\0';
240 valueStartWithDoubleQuote = 0;
245 return strnlen(returned_string, nSize - 1);
248 BOOL check_valid_address(BYTE byCurrXMode, BOOL bIsDwordAddress, DWORD dwCurrAddress)
250 if ((byCurrXMode == XMODE_CLEAR_BITS) || (byCurrXMode == XMODE_SET_BITS) ||
251 (byCurrXMode == XMODE_WRITE_BYTE))
254 if ((TRUE == bIsDwordAddress) && (dwCurrAddress < 0xFFFF))
258 else if ((FALSE == bIsDwordAddress) && (dwCurrAddress > 0xFFFF))
266 void handle_address_change(DWORD dwCurrAddress, DWORD dwPrevAddress, BOOL *bValidDataOffset, BYTE *byDataLength, WORD *wDataLengthOffset, BYTE *m_pBinConfig, WORD *m_wDataOffset, DWORD nTemp)
268 WORD wTemp = (dwCurrAddress - dwPrevAddress - 1);
270 if (*bValidDataOffset)
273 m_pBinConfig[*wDataLengthOffset] = *byDataLength;
274 *bValidDataOffset = FALSE;
277 if ((dwCurrAddress < dwPrevAddress) || (wTemp > 0x7D)) {
279 m_pBinConfig[(*m_wDataOffset)++] = SET_XDATA_ADDRESS;
280 if (nTemp < 0xFFFF) {
281 m_pBinConfig[(*m_wDataOffset)++] = HIBYTE(LOWORD(dwCurrAddress));
282 m_pBinConfig[(*m_wDataOffset)++] = LOBYTE(LOWORD(dwCurrAddress));
284 m_pBinConfig[(*m_wDataOffset)++] = HIBYTE(HIWORD(dwCurrAddress));
285 m_pBinConfig[(*m_wDataOffset)++] = LOBYTE(HIWORD(dwCurrAddress));
286 m_pBinConfig[(*m_wDataOffset)++] = HIBYTE(LOWORD(dwCurrAddress));
287 m_pBinConfig[(*m_wDataOffset)++] = LOBYTE(LOWORD(dwCurrAddress));
291 m_pBinConfig[(*m_wDataOffset)++] = (0x80 | LOBYTE(wTemp));
295 void handle_xdata_mode_switch(BYTE byCurrXMode, BYTE *byPrevXMode, BOOL *bValidDataOffset, BYTE *byDataLength, WORD *wDataLengthOffset, BYTE *m_pBinConfig, WORD *m_wDataOffset) {
296 if (byCurrXMode == XMODE_WRITE_BYTE)
298 if (*bValidDataOffset)
301 m_pBinConfig[*wDataLengthOffset] = *byDataLength;
302 *bValidDataOffset = FALSE;
305 m_pBinConfig[(*m_wDataOffset)++] = CUSTOM_COMMAND;
306 m_pBinConfig[(*m_wDataOffset)++] = byCurrXMode;
308 *byPrevXMode = byCurrXMode;
312 if (byCurrXMode != *byPrevXMode)
314 if (*bValidDataOffset)
317 m_pBinConfig[*wDataLengthOffset] = *byDataLength;
318 *bValidDataOffset = FALSE;
321 m_pBinConfig[(*m_wDataOffset)++] = CUSTOM_COMMAND;
322 m_pBinConfig[(*m_wDataOffset)++] = byCurrXMode;
324 *byPrevXMode = byCurrXMode;
328 BOOL process_key_entry(
char *pszToken,
char *szKeyEntry,
char *szSeparators, BYTE *m_pBinConfig, WORD *m_wDataOffset, DWORD *dwPrevAddress, BYTE *byDataLength, WORD *wDataLengthOffset, BYTE *abyBinBuffer, BOOL *bValidDataOffset)
337 if (!(*bValidDataOffset))
339 *bValidDataOffset = TRUE;
340 *wDataLengthOffset = (*m_wDataOffset)++;
345 if (strstr(szKeyEntry,
".bin"))
347 FILE *fp = fopen(szKeyEntry,
"rb");
353 fseek(fp, 0, SEEK_END);
354 dwActualSize = ftell(fp);
355 fseek(fp, 0, SEEK_SET);
358 rlen = fread(&abyBinBuffer[0], 1, dwActualSize, fp);
361 if (rlen < dwActualSize)
368 for (
int k = 0; k < dwActualSize; k++)
372 m_pBinConfig[(*m_wDataOffset)++] = abyBinBuffer[k];
375 if (0x7F == *byDataLength) {
376 m_pBinConfig[*wDataLengthOffset] = *byDataLength;
377 *wDataLengthOffset = (*m_wDataOffset)++;
386 pszToken = strtok(szKeyEntry, szSeparators);
387 while (pszToken != NULL) {
390 sscanf(pszToken,
"%x", &nTemp);
394 m_pBinConfig[(*m_wDataOffset)++] = byData;
397 if (0x7F == *byDataLength) {
398 m_pBinConfig[*wDataLengthOffset] = *byDataLength;
399 *wDataLengthOffset = (*m_wDataOffset)++;
403 pszToken = strtok(NULL, szSeparators);
410 void handle_stop_opcode(BOOL bValidDataOffset, BYTE byDataLength, BYTE *m_pBinConfig, WORD wDataLengthOffset, WORD *m_wDataOffset)
412 if (bValidDataOffset)
414 if (0 == byDataLength)
416 m_pBinConfig[wDataLengthOffset] = STOP;
420 m_pBinConfig[wDataLengthOffset] = byDataLength;
421 m_pBinConfig[(*m_wDataOffset)++] = STOP;
426 m_pBinConfig[(*m_wDataOffset)++] = STOP;
447 char szKeyList[KEY_BUF_SIZE];
448 WORD m_wDataOffset = 0;
449 char szKeyEntry[KEY_BUF_SIZE];
450 BYTE byPrevXMode = XMODE_WRITE_BYTE;
451 BYTE byCurrXMode = SET_XMODE_NONE;
452 unsigned int nTemp = 0;
453 DWORD dwCurrAddress = 0, dwPrevAddress = 0;
454 BYTE byPatchCount = 0;
455 BOOL bValidDataOffset = FALSE;
456 WORD wDataLengthOffset = 0;
457 BYTE byDataLength = 0;
458 char *pszToken = NULL;
459 char szSeparators[] =
" ,\t";
461 BYTE abyBinBuffer[10 * 1024];
462 BOOL bIsDwordAddress = TRUE;
465 get_key_list(CONFIG_SECTION_NAME,
"NULL",
"EMPTY", szKeyList, KEY_BUF_SIZE, szINIFileName);
467 if (!strcmp(szKeyList,
"EMPTY"))
471 pKeyName = szKeyList;
473 while (strcmp(pKeyName,
""))
475 get_key_list(CONFIG_SECTION_NAME, pKeyName,
"EMPTY", szKeyEntry, KEY_BUF_SIZE, szINIFileName);
477 if (!strcmp(szKeyEntry,
"") || !strcmp(szKeyEntry,
"EMPTY"))
480 pKeyName += (strlen(pKeyName) + 1);
484 if (!strncmp(pKeyName, KEY_XDATA_WRITE, KEY_ID_SIZE))
486 byCurrXMode = XMODE_WRITE_BYTE;
487 sscanf(pKeyName, KEY_XDATA_WRITE
"%x", &nTemp);
488 dwCurrAddress = nTemp;
490 else if (!strncmp(pKeyName, KEY_XDATA_SET, KEY_ID_SIZE))
492 byCurrXMode = XMODE_SET_BITS;
493 sscanf(pKeyName, KEY_XDATA_SET
"%x", &nTemp);
494 dwCurrAddress = nTemp;
496 else if (!strncmp(pKeyName, KEY_XDATA_CLEAR, KEY_ID_SIZE))
498 byCurrXMode = XMODE_CLEAR_BITS;
499 sscanf(pKeyName, KEY_XDATA_CLEAR
"%x", &nTemp);
500 dwCurrAddress = nTemp;
502 else if (!strncmp(pKeyName, KEY_PATCH_CODE, KEY_ID_SIZE))
504 byCurrXMode = XMODE_PATCH_CODE;
505 sscanf(pKeyName, KEY_PATCH_CODE
"%x", &nTemp);
508 if ((TRUE == bIsDwordAddress) && (nTemp < 0xFFFF))
512 else if ((FALSE == bIsDwordAddress) && (nTemp > 0xFFFF))
516 dwCurrAddress = nTemp;
518 if (bValidDataOffset)
521 m_pBinConfig[wDataLengthOffset] = byDataLength;
522 bValidDataOffset = FALSE;
524 m_pBinConfig[m_wDataOffset++] = CUSTOM_COMMAND;
525 m_pBinConfig[m_wDataOffset++] = byCurrXMode;
531 m_pBinConfig[m_wDataOffset++] = HIBYTE(LOWORD(dwCurrAddress));
532 m_pBinConfig[m_wDataOffset++] = LOBYTE(LOWORD(dwCurrAddress));
536 m_pBinConfig[m_wDataOffset++] = HIBYTE(HIWORD(dwCurrAddress));
537 m_pBinConfig[m_wDataOffset++] = LOBYTE(HIWORD(dwCurrAddress));
538 m_pBinConfig[m_wDataOffset++] = HIBYTE(LOWORD(dwCurrAddress));
539 m_pBinConfig[m_wDataOffset++] = LOBYTE(LOWORD(dwCurrAddress));
541 pszToken = strtok(szKeyEntry, szSeparators);
543 sscanf(pszToken,
"%x", &nTemp);
546 m_pBinConfig[m_wDataOffset++] = byData;
547 pszToken = strtok(NULL, szSeparators);
549 pKeyName += (strlen(pKeyName) + 1);
551 byPrevXMode = byCurrXMode;
559 ret = check_valid_address(byCurrXMode, bIsDwordAddress, dwCurrAddress);
565 if (dwCurrAddress != (dwPrevAddress + 1))
567 handle_address_change(dwCurrAddress, dwPrevAddress, &bValidDataOffset, &byDataLength, &wDataLengthOffset, m_pBinConfig, &m_wDataOffset, nTemp);
569 dwPrevAddress = dwCurrAddress;
571 handle_xdata_mode_switch(byCurrXMode, &byPrevXMode, &bValidDataOffset, &byDataLength, &wDataLengthOffset, m_pBinConfig, &m_wDataOffset);
573 if (!process_key_entry(pszToken, szKeyEntry, szSeparators, m_pBinConfig, &m_wDataOffset, &dwPrevAddress, &byDataLength, &wDataLengthOffset, abyBinBuffer, &bValidDataOffset))
579 pKeyName += (strlen(pKeyName) + 1);
581 if (m_wDataOffset <= 1)
586 handle_stop_opcode(bValidDataOffset, byDataLength, m_pBinConfig, wDataLengthOffset, &m_wDataOffset);
589 *binlength = m_wDataOffset;