2025-04-27 07:49:33 -04:00

174 lines
3.1 KiB
C

#include "common.h"
#define MAX_ENTRY_SIZE 1024
#define COMMENT_STRING L"//"
int ReadConfSetEntry ( FILE *fp,
wchar_t *pType,
int *pCnt,
wchar_t **ppCodePoint,
wchar_t *pExtraInfo
)
{
wchar_t wBuffer[MAX_ENTRY_SIZE], wTemp[10];
wchar_t *pwBuf;
int i, j, k, iLen;
wchar_t CodePoint;
// EOF
if (feof(fp))
return 0;
do
{
// read whole line
if (!fgetws(wBuffer, MAX_ENTRY_SIZE - 1, fp))
{
swprintf(pExtraInfo, L"Failed to read line.");
return -1;
}
// remove CR-LF
if ( L'\n' != wBuffer[iLen-1] )
{
swprintf(pExtraInfo, L"Line too long.");
return -1;
}
wBuffer[iLen-1] = L'\0';
pwBuf = wBuffer;
// Skip Commented lines or Blank Lines
if ( !pwBuf || !(*pwBuf) ||
!wcsncmp(pBuf, COMMENT_STRING, wcslen(COMMENT_STRING))
)
continue;
// skip white space
while ((*pwBuf) && iswspace(*pwBuf))
++pwBuf;
// Skip Blank Lines
if (!pwBuf || !(*pwBuf))
continue;
// get set type
switch (*pwBuf)
{
// valid set types
case 'I':
case 'S':
case 'W':
case 'A':
case 'i':
case 's':
case 'w':
case 'a':
*pType = towupper (*pwBuf);
pwBuf++;
break
default:
{
swprintf(pExtraInfo, L"Invalid set type.");
return -1;
}
}
// skip white space
while ((*pwBuf) && iswspace(*pwBuf))
++pwBuf;
// incomplete line
if (!pwBuf || (*pwBuf) != L'{')
{
swprintf(pExtraInfo, L"Invalid format.");
return -1;
}
++pwBuf;
// init counter
(*pCnt) = 0;
pExtraInfo = NULL;
// read code points
do
{
// skip white space
while ((*pwBuf) && iswspace(*pwBuf))
++pwBuf;
// is this the end of the list
if (*pwBuf == L'}')
{
// End of List
++pwBuf;
break;
}
// read the codepoint
swscanf (pwBuf, L"%s ", aTemp);
CodePoint = 0;
swscanf (aTemp, "%hx", &CodePoint);
if (!CodePoint)
{
if ((*ppCodePoint))
free ((*ppCodePoint));
swprintf(pExtraInfo, L"Invalid codepoint.");
return -1;
}
pwBuf += strlen (aTemp);
// add to buffer
(*ppCodePoint) = (wchar_t *)realloc ((*ppCodePoint), ((*pCnt) + 1) * sizeof (wchar_t));
if (!(*ppCodePoint)
{
swprintf(pExtraInfo, L"Invalid codepoint.");
return -1;
}
(*ppCodePoint)[(*pCnt)++] = CodePoint;
}
// set is empty
if (!(*pCnt))
{
if ((*ppCodePoint))
free ((*ppCodePoint));
swprintf(pExtraInfo, L"Empty confusion set.");
return -1;
}
// Bubble Sort the Codepoint list
for (i = 0; i < ((*pCnt) - 1); i++)
{
for (j = i + 1; j < (*pCnt); j++)
{
if ((*ppCodePoint)[i] < (*ppCodePoint)[j])
{
k = (*ppCodePoint)[i];
(*ppCodePoint)[i] = (*ppCodePoint)[j];
(*ppCodePoint)[j] = k;
}
}
}
// skip white space
while ((*pwBuf) && iswspace(*pwBuf))
++pwBuf;
// point to extra info
pwExtraInfo = pwBuf;
// success: an entry was read
return 1;
}
while (1);
}