mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
a0e47b7e20
* added verified signer name (doesn't work for catalogs yet) git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1424 21ef857c-d57f-4fe0-8362-d861dc6d29cd
238 lines
6.8 KiB
C#
238 lines
6.8 KiB
C#
using System;
|
|
using System.Text;
|
|
|
|
namespace ProcessHacker.Common
|
|
{
|
|
public class Tokenizer
|
|
{
|
|
private string _text;
|
|
private int _i = 0;
|
|
|
|
public Tokenizer(string text)
|
|
{
|
|
_text = text;
|
|
}
|
|
|
|
public int Index
|
|
{
|
|
get { return _i; }
|
|
set { _i = value; }
|
|
}
|
|
|
|
public string EatId()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
while (_i < _text.Length)
|
|
{
|
|
// identifiers can't start with a number-
|
|
if (sb.Length == 0)
|
|
{
|
|
if (!(char.IsLetter(_text[_i]) || _text[_i] == '_'))
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (!(char.IsLetterOrDigit(_text[_i]) || _text[_i] == '_'))
|
|
break;
|
|
}
|
|
|
|
sb.Append(_text[_i]);
|
|
_i++;
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string EatNumber()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
while (_i < _text.Length)
|
|
{
|
|
// allow hex numbers and floating-point numbers
|
|
if (sb.Length == 1 && sb[0] == '0')
|
|
{
|
|
if (!char.IsDigit(_text[_i]) && char.ToLower(_text[_i]) != 'x' && _text[_i] != '.')
|
|
break;
|
|
}
|
|
else if (sb.Length >= 2 && sb[0] == '0' && char.ToLower(sb[1]) == 'x')
|
|
{
|
|
if (!(char.IsDigit(_text[_i]) ||
|
|
char.ToLower(_text[_i]) == 'a' ||
|
|
char.ToLower(_text[_i]) == 'b' ||
|
|
char.ToLower(_text[_i]) == 'c' ||
|
|
char.ToLower(_text[_i]) == 'd' ||
|
|
char.ToLower(_text[_i]) == 'e' ||
|
|
char.ToLower(_text[_i]) == 'f'))
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (!char.IsDigit(_text[_i]))
|
|
break;
|
|
}
|
|
|
|
sb.Append(_text[_i]);
|
|
_i++;
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string EatQuotedString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
bool inEscape = false;
|
|
|
|
if (_text[_i] == '"')
|
|
{
|
|
_i++;
|
|
}
|
|
else
|
|
return "";
|
|
|
|
while (_i < _text.Length)
|
|
{
|
|
if (_text[_i] == '\\')
|
|
{
|
|
inEscape = true;
|
|
_i++;
|
|
continue;
|
|
}
|
|
else if (inEscape)
|
|
{
|
|
if (_text[_i] == '\\')
|
|
sb.Append('\\');
|
|
else if (_text[_i] == '"')
|
|
sb.Append('"');
|
|
else if (_text[_i] == '\'')
|
|
sb.Append('\'');
|
|
else if (_text[_i] == 'r')
|
|
sb.Append('\r');
|
|
else if (_text[_i] == 'n')
|
|
sb.Append('\n');
|
|
else if (_text[_i] == 't')
|
|
sb.Append('\t');
|
|
else
|
|
throw new Exception("Unrecognized escape sequence '\\" + _text[_i] + "'");
|
|
|
|
_i++;
|
|
inEscape = false;
|
|
continue;
|
|
}
|
|
else if (_text[_i] == '"')
|
|
{
|
|
_i++;
|
|
break;
|
|
}
|
|
|
|
sb.Append(_text[_i]);
|
|
_i++;
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string EatSymbol()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
while (_i < _text.Length && sb.Length < 1) // we need a proper parser to solve this
|
|
{
|
|
char c = _text[_i];
|
|
|
|
if (c < ' ' || c > '~') // check if its an ASCII character
|
|
break;
|
|
if (char.IsLetterOrDigit(c) || c == '_') // check if its eligible to be an identifier
|
|
break;
|
|
|
|
sb.Append(c);
|
|
_i++;
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string EatUntil(char c)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
while (_text[_i] != c && _i < _text.Length)
|
|
{
|
|
sb.Append(_text[_i]);
|
|
_i++;
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public bool EatWhitespace()
|
|
{
|
|
return this.EatWhitespace(false);
|
|
}
|
|
|
|
public bool EatWhitespace(bool comments)
|
|
{
|
|
bool ranOut = true;
|
|
bool preComment = false; // '/'
|
|
bool inComment = false; // '*'
|
|
bool prePostComment = false; // '*'
|
|
|
|
while (_i < _text.Length)
|
|
{
|
|
if (comments && inComment && _text[_i] == '*')
|
|
{
|
|
prePostComment = true;
|
|
_i++;
|
|
continue;
|
|
}
|
|
else if (comments && prePostComment && _text[_i] == '/')
|
|
{
|
|
prePostComment = false;
|
|
inComment = false;
|
|
_i++;
|
|
continue;
|
|
}
|
|
else if (comments && !inComment && _text[_i] == '/')
|
|
{
|
|
preComment = true;
|
|
_i++;
|
|
continue;
|
|
}
|
|
else if (comments && preComment)
|
|
{
|
|
if (_text[_i] == '*')
|
|
{
|
|
preComment = false;
|
|
inComment = true;
|
|
_i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
// it's a mistake, revert!
|
|
_i -= 1;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
preComment = false;
|
|
prePostComment = false;
|
|
}
|
|
|
|
if (!(_text[_i] == '\r' || _text[_i] == '\n' || _text[_i] == ' ' || _text[_i] == '\t') && !inComment)
|
|
{
|
|
ranOut = false;
|
|
break;
|
|
}
|
|
|
|
_i++;
|
|
}
|
|
|
|
return ranOut;
|
|
}
|
|
}
|
|
}
|