diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclClock.c | 2 | ||||
-rw-r--r-- | generic/tclClockFmt.c | 102 |
2 files changed, 83 insertions, 21 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c index 3c296b5..e00d6a2 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2576,6 +2576,7 @@ ClockScanObjCmd( } ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } +#if 0 else if (1) { /* TODO: Tcled Scan proc - */ @@ -2588,6 +2589,7 @@ ClockScanObjCmd( Tcl_DecrRefCount(callargs[0]); return ret; } +#endif else { /* Use compiled version of Scan - */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 356965d..93416af 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -392,19 +392,32 @@ Tcl_GetClockFrmScnFromObj( } -#define AllocTokenInChain(tok, chain, tokC) \ - if ((tok) >= (chain) + (tokC)) { \ +#define AllocTokenInChain(tok, chain, tokCnt) \ + if (++(tok) >= (chain) + (tokCnt)) { \ (char *)(chain) = ckrealloc((char *)(chain), \ - (tokC) + sizeof((**(tok))) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); \ - if ((chain) == NULL) { return NULL; }; \ - (tok) = (chain) + (tokC); \ - (tokC) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ - } - -const char *ScnSTokenChars = "dmyYHMS"; -static ClockScanToken ScnSTokens[] = { + (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ + if ((chain) == NULL) { goto done; }; \ + (tok) = (chain) + (tokCnt); \ + (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ + } \ + *(tok) = NULL; + +const char *ScnSTokenMapChars = + "dmyYHMS"; +static ClockScanToken ScnSTokenMap[] = { + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 4, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, {CTOKT_DIGIT, 1, 2, 0}, }; +const char *ScnSpecTokenMapChars = + " %"; +static ClockScanToken ScnSpecTokenMap[] = { + {CTOKT_SPACE, 1, 0xffff, 0}, +}; /* *---------------------------------------------------------------------- @@ -435,31 +448,73 @@ ClockGetOrParseScanFormat( /* if first time scanning - tokenize format */ if (fss->scnTok == NULL) { const char *strFmt; - register const char *p, *e; + register const char *p, *e, *cp, *word_start = NULL; + + Tcl_MutexLock(&ClockFmtMutex); fss->scnTokC = CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; fss->scnTok = - tok = ckalloc(sizeof(**tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); - (*tok)->type = CTOKT_EOB; + tok = ckalloc(sizeof(*tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); + *tok = NULL; strFmt = TclGetString(formatObj); for (e = p = strFmt, e += formatObj->length; p != e; p++) { switch (*p) { case '%': - if (p+1 >= e) - goto word_tok; - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + if (p+1 >= e) { + word_start = p; + continue; + } p++; - // *tok = + /* try to find modifier: */ + switch (*p) { + case '%': + word_start = p-1; + continue; + break; + case 'E': + goto ext_tok_E; + break; + case 'O': + goto ext_tok_O; + break; + default: + cp = strchr(ScnSTokenMapChars, *p); + if (!cp || *cp == '\0') { + word_start = p-1; + continue; + } + *tok = &ScnSTokenMap[cp - ScnSTokenMapChars]; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + break; + } break; case ' ': + cp = strchr(ScnSpecTokenMapChars, *p); + if (!cp || *cp == '\0') { + p--; + goto word_tok; + } + *tok = &ScnSpecTokenMap[cp - ScnSpecTokenMapChars]; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); - // *tok = break; default: word_tok: - break; + + continue; } + + continue; +ext_tok_E: + +ext_tok_O: + + /*******************/ + continue; + } + +done: + Tcl_MutexUnlock(&ClockFmtMutex); } return fss->scnTok; @@ -478,11 +533,16 @@ ClockScan( { ClockScanToken **tok; - if (ClockGetOrParseScanFormat(interp, opts->formatObj) == NULL) { + if ((tok = ClockGetOrParseScanFormat(interp, opts->formatObj)) == NULL) { return TCL_ERROR; } - // Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)fss)); + //*********************************** + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)tok)); + return TCL_OK; + + return TCL_ERROR; } |