**** Merged from MCS ****
[mono-project.git] / mcs / ilasm / scanner / StringHelper.cs
blob247e5c6e3b4a11a4e74136d4526670e70c575859
1 // StringHelper.cs
2 // Author: Sergey Chaban (serge@wildwestsoftware.com)
4 using System;
5 using System.Text;
7 namespace Mono.ILASM {
9 /// <summary>
10 /// </summary>
11 internal class StringHelper : StringHelperBase {
13 private static readonly string idChars = "_$@?";
15 /// <summary>
16 /// </summary>
17 /// <param name="host"></param>
18 public StringHelper (ILTokenizer host) : base (host)
23 /// <summary>
24 /// </summary>
25 /// <returns></returns>
26 public override bool Start (char ch)
28 mode = Token.UNKNOWN;
30 if (Char.IsLetter (ch) || idChars.IndexOf (ch) != -1) {
31 mode = Token.ID;
32 } else if (ch == '\'') {
33 mode = Token.SQSTRING;
34 } else if (ch == '"') {
35 mode = Token.QSTRING;
38 return (mode != Token.UNKNOWN);
42 private static bool IsIdChar (int c)
44 char ch = (char) c;
45 return (Char.IsLetterOrDigit(ch) || idChars.IndexOf (ch) != -1);
48 /// <summary>
49 /// </summary>
50 /// <returns></returns>
51 public override string Build ()
53 if (mode == Token.UNKNOWN) return String.Empty;
54 int ch = 0;
56 ILReader reader = host.Reader;
58 StringBuilder idsb = new StringBuilder ();
59 if (mode == Token.SQSTRING || mode == Token.QSTRING) {
60 int term = (mode == Token.SQSTRING) ? '\'' : '"';
61 reader.Read (); // skip quote
62 for (ch = reader.Read (); ch != -1; ch = reader.Read ()) {
63 if (ch == term) {
64 break;
67 if (ch == '\\') {
68 ch = reader.Read ();
71 * Long string can be broken across multiple lines
72 * by using '\' as the last char in line.
73 * Any white space chars between '\' and the first
74 * char on the next line are ignored.
76 if (ch == '\n') {
77 reader.SkipWhitespace ();
78 continue;
81 int escaped = Escape (ch);
82 if (escaped == -1) {
83 reader.Unread (ch);
84 ch = '\\';
85 } else {
86 ch = escaped;
90 idsb.Append((char)ch);
92 } else { // ID
93 while ((ch = reader.Read ()) != -1) {
94 if (IsIdChar (ch)) {
95 idsb.Append ((char) ch);
96 } else {
97 reader.Unread (ch);
98 break;
102 return idsb.ToString ();
108 /// <summary>
109 /// </summary>
110 /// <param name="ch"></param>
111 /// <returns></returns>
112 public static int Escape (int ch)
114 int res = -1;
116 if (ch >= '0' && ch <='7') {
117 //TODO : octal code
118 } else {
119 int id = "abfnrtv\"'\\".IndexOf ((char)ch);
120 if (id != -1) {
121 res = "\a\b\f\n\r\t\v\"'\\" [id];
125 return res;