1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
/*
* Copyright (C) 1999-2002 Stijn van Dongen.
*/
#include <string.h>
#include "parse.h"
#include "ilist.h"
#include "util/txt.h"
#include "util/buf.h"
#include "util/types.h"
char mcxIntalgRangeToken = '-';
Ilist* ilParseIntSet
( const char* string
, mcxOnFail ON_FAIL
)
{ mcxBuf ibuf
; mcxTing *itxt
; char *token
; const char *msg
; int left, right, i
; int *ip
; Ilist *il
; il = ilInit(NULL)
; mcxBufInit(&ibuf, &il->list, sizeof(int), 20)
; itxt = mcxTingNew(string)
; token = strtok(itxt->str, ",")
; while(token)
{
int tokenlen = strlen(token)
; if (strchr(token, mcxIntalgRangeToken))
{
mcxTing *fmtTxt = mcxTingNew("%d.%d")
; *(fmtTxt->str+2) = mcxIntalgRangeToken
; if (sscanf(token, fmtTxt->str, &left, &right) == 2)
{ for (i=left;i<=right;i++)
{ ip = (int *) mcxBufExtend(&ibuf, 1)
; *ip = i
; }
; }
else
{ msg = "invalid range specification in string"
; goto parseError
; }
; mcxTingFree(&fmtTxt)
; }
else if (tokenlen)
{
int n = 0
; ip = (int *) mcxBufExtend(&ibuf, 1)
; if ((sscanf(token, "%d%n", ip, &n) != 1) || n != tokenlen)
{ msg = "invalid int specification in string"
; goto parseError
; }
; }
else if (0)
{
parseError:
fprintf
( stderr
, "[parseIntSet] %s [%s]\n"
, msg
, token
)
; if (ON_FAIL == RETURN_ON_FAIL)
return(NULL)
; else
exit(1)
; }
else
{ msg = "empty string with comma-boundary not allowed"
; goto parseError
/* we actually never reach this place because strtok
* skips the empty records for us. It has no consistent way of giving
* us a correct offset.
*/
; }
; token = strtok(NULL, ",")
; }
; mcxTingFree(&itxt)
; il->n = mcxBufFinalize(&ibuf)
; return(il)
; }
|