123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- #include "shellmatta_opt.h"
- #include "shellmatta_utils.h"
- #include "shellmatta.h"
- #include <string.h>
- static shellmatta_retCode_t findNextHunk(shellmatta_instance_t *inst)
- {
- shellmatta_retCode_t ret = SHELLMATTA_ERROR;
- uint32_t newOffset = inst->optionParser.nextOffset;
- uint32_t exeptionOffset = 0u;
- char quotation = '\0';
-
- while( (newOffset < inst->inputCount)
- && ((' ' == inst->buffer[newOffset])
- || ('\0' == inst->buffer[newOffset])))
- {
- newOffset ++;
- }
- inst->optionParser.offset = newOffset;
-
- while((newOffset < inst->inputCount)
- && (((' ' != inst->buffer[newOffset]) && ('\0' != inst->buffer[newOffset])) || '\0' != quotation))
- {
-
- if((('\'' == inst->buffer[newOffset]) || ('"' == inst->buffer[newOffset])) && (quotation == '\0'))
- {
- quotation = inst->buffer[newOffset];
- exeptionOffset ++;
- }
-
- else if(quotation == inst->buffer[newOffset])
- {
- exeptionOffset ++;
-
- if('\\' != inst->buffer[newOffset - 1u])
- {
- quotation = '\0';
- }
- else
- {
- inst->buffer[newOffset - exeptionOffset] = inst->buffer[newOffset];
- }
- }
- else
- {
-
- if(0u != exeptionOffset)
- {
- inst->buffer[newOffset - exeptionOffset] = inst->buffer[newOffset];
- }
- }
- newOffset ++;
- }
- inst->optionParser.nextOffset = newOffset;
- inst->optionParser.len = newOffset - inst->optionParser.offset - exeptionOffset;
-
- inst->buffer[inst->optionParser.offset + inst->optionParser.len] = '\0';
- if((inst->optionParser.offset < inst->inputCount) && (0u != inst->optionParser.len) && ('\0' == quotation))
- {
- ret = SHELLMATTA_OK;
- }
- return ret;
- }
- static char peekNextHunk(shellmatta_instance_t *inst)
- {
- uint32_t newOffset = inst->optionParser.nextOffset;
-
- while( (newOffset < inst->inputCount)
- && ((' ' == inst->buffer[newOffset])
- || ('\0' == inst->buffer[newOffset])))
- {
- newOffset ++;
- }
- return inst->buffer[newOffset];
- }
- static shellmatta_retCode_t parseShortOpt( shellmatta_instance_t *inst,
- const char *optionString,
- char *option,
- shellmatta_opt_argtype_t *argtype)
- {
- shellmatta_retCode_t ret = SHELLMATTA_ERROR;
- char *buffer = &inst->buffer[inst->optionParser.offset];
- uint32_t i;
-
- if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' != buffer[1u]) && ('\0' != buffer[1u]))
- {
- *option = '\0';
-
- for(i = 0u; ('\0' != optionString[i]) && ('\0' == *option); i ++)
- {
- if(buffer[1u] == optionString[i])
- {
- ret = SHELLMATTA_OK;
-
- *option = buffer[1u];
-
- if(':' == optionString[i + 1u])
- {
- *argtype = SHELLMATTA_OPT_ARG_REQUIRED;
- if(':' == optionString[i + 2u])
- {
- *argtype = SHELLMATTA_OPT_ARG_OPTIONAL;
- }
- }
- else
- {
- *argtype = SHELLMATTA_OPT_ARG_NONE;
- }
- }
- }
- }
-
- else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
- {
- ret = SHELLMATTA_CONTINUE;
- }
- else
- {
- *option = '\0';
- }
- return ret;
- }
- static shellmatta_retCode_t parseLongOpt( shellmatta_instance_t *inst,
- const shellmatta_opt_long_t *longOptions,
- char *option,
- shellmatta_opt_argtype_t *argtype)
- {
- shellmatta_retCode_t ret = SHELLMATTA_ERROR;
- char *buffer = &inst->buffer[inst->optionParser.offset];
- uint32_t i;
-
- if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' != buffer[1u]) && ('\0' != buffer[1u]))
- {
-
- for(i = 0u; ('\0' != longOptions[i].paramShort) && ('\0' == *option); i ++)
- {
- if(buffer[1u] == longOptions[i].paramShort)
- {
- ret = SHELLMATTA_OK;
-
- *option = longOptions[i].paramShort;
- *argtype = longOptions[i].argtype;
- }
- }
- }
-
- else if((3u <= inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
- {
-
- for(i = 0u; ('\0' != longOptions[i].paramShort) && ('\0' == *option); i ++)
- {
- if(0 == strcmp(&buffer[2u], longOptions[i].paramLong))
- {
- ret = SHELLMATTA_OK;
-
- *option = longOptions[i].paramShort;
- *argtype = longOptions[i].argtype;
- }
- }
- }
-
- else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
- {
- *option = '\0';
- ret = SHELLMATTA_CONTINUE;
- }
- else
- {
- *option = '\0';
- }
- return ret;
- }
- static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t handle,
- const char *optionString,
- const shellmatta_opt_long_t *longOptions,
- char *option,
- char **argument,
- uint32_t *argLen)
- {
- shellmatta_retCode_t ret = SHELLMATTA_USE_FAULT;
- shellmatta_instance_t *inst = (shellmatta_instance_t*)handle;
- shellmatta_opt_argtype_t argtype = SHELLMATTA_OPT_ARG_NONE;
-
- if( (NULL != inst)
- && (SHELLMATTA_MAGIC == inst->magic)
- && (NULL != option))
- {
- *option = '\0';
- if(NULL != argument)
- {
- *argument = NULL;
- }
- if(NULL != argLen)
- {
- *argLen = 0u;
- }
-
- do
- {
- ret = findNextHunk(inst);
- if(SHELLMATTA_OK == ret)
- {
-
- if(NULL != optionString)
- {
- ret = parseShortOpt(inst, optionString, option, &argtype);
- }
- else if(NULL != longOptions)
- {
- ret = parseLongOpt(inst, longOptions, option, &argtype);
- }
- else
- {
- ret = SHELLMATTA_USE_FAULT;
- }
-
- if(SHELLMATTA_ERROR == ret)
- {
- if(NULL != argument)
- {
- *argument = &(inst->buffer[inst->optionParser.offset]);
- }
- if(NULL != argLen)
- {
- *argLen = inst->optionParser.len;
- }
- ret = SHELLMATTA_OK;
- }
- else if(SHELLMATTA_USE_FAULT == ret)
- {
-
- }
- else
- {
- switch(argtype)
- {
- case SHELLMATTA_OPT_ARG_REQUIRED:
- ret = findNextHunk(inst);
- if((NULL == argument) || (NULL == argLen))
- {
- ret = SHELLMATTA_USE_FAULT;
- }
- if(SHELLMATTA_OK == ret)
- {
- *argument = &(inst->buffer[inst->optionParser.offset]);
- *argLen = inst->optionParser.len;
- }
- break;
- case SHELLMATTA_OPT_ARG_OPTIONAL:
-
- if('-' != peekNextHunk(inst))
- {
- ret = findNextHunk(inst);
- if((NULL == argument) || (NULL == argLen))
- {
- ret = SHELLMATTA_USE_FAULT;
- }
- if(SHELLMATTA_OK == ret)
- {
- *argument = &(inst->buffer[inst->optionParser.offset]);
- *argLen = inst->optionParser.len;
- }
- }
- break;
- default:
-
- break;
- }
- }
- }
- } while(SHELLMATTA_CONTINUE == ret);
- }
- return ret;
- }
- shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle,
- const char *optionString,
- char *option,
- char **argument,
- uint32_t *argLen)
- {
- return shellmatta_opt_int( handle,
- optionString,
- NULL,
- option,
- argument,
- argLen);
- }
- shellmatta_retCode_t shellmatta_opt_long( shellmatta_handle_t handle,
- const shellmatta_opt_long_t *longOptions,
- char *option,
- char **argument,
- uint32_t *argLen)
- {
- return shellmatta_opt_int( handle,
- NULL,
- longOptions,
- option,
- argument,
- argLen);
- }
- void shellmatta_opt_init(shellmatta_instance_t *inst, uint32_t argStart)
- {
-
- inst->optionParser.argStart = argStart;
- inst->optionParser.nextOffset = argStart;
- }
- void shellmatta_opt_reInit(shellmatta_instance_t *inst)
- {
-
- inst->optionParser.nextOffset = inst->optionParser.argStart;
- }
|