📄 tokenscan.c
字号:
/* TSScanInit() - initialize scanner to scan a buffer. TSScan() - pull successive tokens out of a character. Returns NULL when there are no more. Has the property that once it returns NULL, succeeding calls continue to return NULL until TSScanInit() is called again. Default behavior is that tokens are sequences of non-blank characters, or quotes can be used to allow whitespace characters in the token. The '\' character turns off any special meaning of the following character. TSSetScanner () - install scanner. TSGetScanner () - get current scanner. TSSetScanPos() - set current position within scan buffer. TSGetScanPos() - get current position within scan buffer. TSIsScanDelim() - test whether character is in current delimiter set. TSIsScanQuote() - test whether character is in current quote set. TSIsScanEscape() - test whether character is in current escape set. TSIsScanEos() - test whether character is in current EOS set. TSTestScanFlags() - test whether scanner flags are set. The original buffer is destroyed by scanning, since null bytes are placed after each token as they are found. 12 Apr 90 Created (as part of NIO). 25 Sep 90 Reorganized to allow accommodating alternate scanners while preserving current scan position within buffer. 26 Oct 90 Removed from NIO and made into separate library. 25 Sep 91 Parameterized the quote and escape characters. 06 Oct 93 Added scanFlags field to scanner structure. Only flag so far is to allow all delimiter characters to be significant (so scanner stops on each one, rather than treating sequences of contiguous delimiters as one delimiter). 14 Oct 93 Parameterized the end-of-string characters.*/# include <stdio.h># include "tokenscan.h"typedef void (*VoidProc) ();typedef char * (*CharPtrProc) ();static int Search ();static char *CanonScan ();static TSScanner defScan = { (VoidProc) NULL, CanonScan, " \t", "\"'", "\\", "\n\r", 0 };static TSScanner curScan = { (VoidProc) NULL, CanonScan, " \t", "\"'", "\\", "\n\r", 0 };static char *curPos;static int emptyToken;voidTSScanInit (p)char *p;{ curPos = p; emptyToken = 0; if (curScan.scanInit != (VoidProc) NULL) (*curScan.scanInit) (p);}voidTSSetScanner (p)TSScanner *p;{ if (p == (TSScanner *) NULL || p->scanInit == (VoidProc) NULL) curScan.scanInit = defScan.scanInit; else curScan.scanInit = p->scanInit; if (p == (TSScanner *) NULL || p->scanScan == (CharPtrProc) NULL) curScan.scanScan = defScan.scanScan; else curScan.scanScan = p->scanScan; if (p == (TSScanner *) NULL || p->scanDelim == (char *) NULL) curScan.scanDelim = defScan.scanDelim; else curScan.scanDelim = p->scanDelim; if (p == (TSScanner *) NULL || p->scanQuote == (char *) NULL) curScan.scanQuote = defScan.scanQuote; else curScan.scanQuote = p->scanQuote; if (p == (TSScanner *) NULL || p->scanEscape == (char *) NULL) curScan.scanEscape = defScan.scanEscape; else curScan.scanEscape = p->scanEscape; if (p == (TSScanner *) NULL || p->scanEos == (char *) NULL) curScan.scanEos = defScan.scanEos; else curScan.scanEos = p->scanEos; if (p == (TSScanner *) NULL || p->scanFlags == 0) curScan.scanFlags = defScan.scanFlags; else curScan.scanFlags = p->scanFlags;}voidTSGetScanner (p)TSScanner *p;{ p->scanInit = curScan.scanInit; p->scanScan = curScan.scanScan; p->scanDelim = curScan.scanDelim; p->scanQuote = curScan.scanQuote; p->scanEscape = curScan.scanEscape; p->scanEos = curScan.scanEos; p->scanFlags = curScan.scanFlags;}voidTSSetScanPos (p)char *p;{ curPos = p;}char *TSGetScanPos (){ return (curPos);}/* * Search a (possibly NULL) string for a character. */static intSearch (s, c)char *s;char c;{char c2; if (s != (char *) NULL) { while ((c2 = *s++) != '\0') { if (c == c2) return (1); } } return (0);}intTSIsScanDelim (c)char c;{ return (Search (curScan.scanDelim, c));}intTSIsScanQuote (c)char c;{ return (Search (curScan.scanQuote, c));}intTSIsScanEscape (c)char c;{ return (Search (curScan.scanEscape, c));}intTSIsScanEos (c)char c;{ if (c == '\0') /* null character ALWAYS terminates string */ return (1); return (Search (curScan.scanEos, c));}intTSTestScanFlags (flags)int flags;{ return ((curScan.scanFlags & flags) == flags);}char *TSScan (){ return ((*curScan.scanScan) ());}static char *CanonScan (){char *pos, *start, *p, c, quote = 0;int escape = 0, haveToken = 0; if (emptyToken) /* fix to point into buffer */ { emptyToken = 0; return (""); } pos = TSGetScanPos (); if (!TSTestScanFlags (tsNoConcatDelims)) { while (TSIsScanDelim (*pos)) /* skip delimiters */ ++pos; } start = p = pos; /* start of token */ while (!TSIsScanEos (c = *pos)) /* eos terminates any token */ { haveToken = 1; if (escape) /* previous char was escape; */ { /* pass this one literally */ *p++ = *pos++; escape = 0; } else if (TSIsScanEscape (c)) /* this char is escape; */ { /* pass next one literally */ ++pos; escape = 1; } else if (quote) /* in quote mode */ { if (c == quote) /* end quote mode */ quote = 0; else /* no end quote yet */ *p++ = *pos; /* add char */ ++pos; /* skip to next char */ } else if (TSIsScanQuote (c)) /* begin quote mode */ { ++pos; quote = c; } else if (TSIsScanDelim (c)) /* end of token */ { ++pos; /* skip past delimiter */ /* * If also end of string and all delims are significant, * there's an implicit empty token at end. We won't be * able to tell that from looking at the string itself, * so set a flag for next call. */ if (TSIsScanEos (*pos) && TSTestScanFlags (tsNoConcatDelims)) ++emptyToken; break; } else *p++ = *pos++; } *p = '\0'; TSSetScanPos (pos); return (haveToken ? start : (char *) NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -