Skip to content

Instantly share code, notes, and snippets.

@heksesang
Last active August 5, 2018 14:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heksesang/b15057fe3f093eebee3a to your computer and use it in GitHub Desktop.
Save heksesang/b15057fe3f093eebee3a to your computer and use it in GitHub Desktop.
Parses the encoding profiles in CASC encoding files.
#include <string.h>
#include <stdint.h>
void *memAlloc(size_t count)
{
char* ptr = new char[count] {};
return ptr;
}
void memFree(void* ptr) { free(ptr); }
bool isWhitespace(int value)
{
bool result;
result = value == ' ' || value == '\t' || value == '\v' || value == '\r' || value == '\f' || value == '\n';
return result;
}
int parseEncodingProfile(char *encodingProfile, char **encodingMode, char ***params, unsigned int *nParams)
{
char *it;
for (it = encodingProfile; ; ++it)
{
if (!isWhitespace(*it))
break;
}
for (*encodingMode = it; *it; ++it)
{
if (*it == ':' || isWhitespace(*it))
break;
}
char *encodingModeEnd = it;
while (isWhitespace(*it))
{
++it;
}
if (*it != '\0')
{
if (*it != ':')
return 0;
*encodingModeEnd = '\0';
do
{
++it;
} while (isWhitespace(*it));
if (*it == '{')
{
do
{
++it;
} while (isWhitespace(*it));
*nParams = 1;
if (!*it)
return 0;
char *paramsStart = it;
int state = 1;
do
{
if (!isWhitespace(*it))
{
if (!state)
return 0;
if (*it == '{')
{
state++;
}
else
{
if (*it == '}')
{
--state;
}
else
{
if (*it == ',' && state == 1)
++*nParams;
}
}
}
} while (*++it);
if (state)
return 0;
char **paramArray = (char **)memAlloc(4 * (*nParams) | -((uint64_t)*nParams >> 30 != 0));
if (*params)
memFree(*params);
*params = paramArray;
int paramIndex = 0;
**params = paramsStart;
for (int state = 1; *paramsStart; ++paramsStart)
{
if (*paramsStart != ' ' && *paramsStart != '\t' && *paramsStart != '\v' && *paramsStart != '\r' && *paramsStart != '\f' && *paramsStart != '\n')
{
if (!state)
return 0;
if (*paramsStart == '{')
{
++state;
}
else if (*paramsStart == '}')
{
--state;
if (!state)
{
char *paramsEnd;
for (paramsEnd = paramsStart; paramsEnd > (*params)[paramIndex]; --paramsEnd)
{
char ch = *(paramsEnd - 1);
if (ch != ' ' && ch != '\t' && ch != '\v' && ch != '\r' && ch != '\f' && ch != '\n')
break;
}
*paramsEnd = '\0';
}
}
else if (*paramsStart == ',' && state == 1)
{
char *paramsEnd = paramsStart;
if (paramsStart > (*params)[paramIndex])
{
do
{
if (!isWhitespace(*(paramsEnd - 1)))
break;
--paramsEnd;
} while (paramsEnd > (*params)[paramIndex]);
}
*paramsEnd = '\0';
++paramIndex;
for (; *paramsStart; ++paramsStart)
{
if (!isWhitespace(paramsStart[1]))
break;
}
(*params)[paramIndex] = paramsStart + 1;
}
}
}
if (paramIndex + 1 != *nParams)
abort();
}
else
{
*nParams = 1;
char **paramArray = (char **)memAlloc(4);
if (*params)
memFree(*params);
*params = paramArray;
**params = it;
for (it = &it[strlen(it)]; it > **params; --it)
{
char ch = *(it - 1);
if (ch != ' ' && ch != '\t' && ch != '\v' && ch != '\r' && ch != '\f' && ch != '\n')
break;
}
*it = '\0';
}
if (*nParams == 1 && !***params)
{
*nParams = 0;
if (*params)
memFree(*params);
*params = 0;
}
}
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment