* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / ilasm / scanner / StringHelper.cs
1 // StringHelper.cs\r
2 // Author: Sergey Chaban (serge@wildwestsoftware.com)\r
3 \r
4 using System;\r
5 using System.Text;\r
6 \r
7 namespace Mono.ILASM {\r
8 \r
9         /// <summary>\r
10         /// </summary>\r
11         internal class StringHelper : StringHelperBase {\r
12 \r
13                 private static readonly string idChars = "_$@?`";\r
14 \r
15                 /// <summary>\r
16                 /// </summary>\r
17                 /// <param name="host"></param>\r
18                 public StringHelper (ILTokenizer host) : base (host)\r
19                 {\r
20                 }\r
21 \r
22 \r
23                 /// <summary>\r
24                 /// </summary>\r
25                 /// <returns></returns>\r
26                 public override bool Start (char ch)\r
27                 {\r
28                         mode = Token.UNKNOWN;\r
29 \r
30                         if (Char.IsLetter (ch) || idChars.IndexOf (ch) != -1) {\r
31                                 mode = Token.ID;\r
32                         } else if (ch == '\'') {\r
33                                 mode = Token.SQSTRING;\r
34                         } else if (ch == '"') {\r
35                                 mode = Token.QSTRING;\r
36                         }\r
37 \r
38                         return (mode != Token.UNKNOWN);\r
39                 }\r
40 \r
41 \r
42                 private static bool IsIdChar (int c)\r
43                 {\r
44                         char ch = (char) c;\r
45                         return (Char.IsLetterOrDigit(ch) || idChars.IndexOf (ch) != -1);\r
46                 }\r
47 \r
48                 /// <summary>\r
49                 /// </summary>\r
50                 /// <returns></returns>\r
51                 public override string Build ()\r
52                 {\r
53                         if (mode == Token.UNKNOWN) return String.Empty;\r
54                         int ch = 0;\r
55 \r
56                         ILReader reader = host.Reader;\r
57 \r
58                         StringBuilder idsb = new StringBuilder ();\r
59                         if (mode == Token.SQSTRING || mode == Token.QSTRING) {\r
60                                 int term = (mode == Token.SQSTRING) ? '\'' : '"';\r
61                                 reader.Read (); // skip quote\r
62                                 for (ch = reader.Read (); ch != -1; ch = reader.Read ()) {\r
63                                         if (ch == term) {\r
64                                                 break;\r
65                                         }\r
66 \r
67                                         if (ch == '\\') {\r
68                                                 ch = reader.Read ();\r
69 \r
70                                                 /*\r
71                                                  * Long string can be broken across multiple lines\r
72                                                  * by using '\' as the last char in line.\r
73                                                  * Any white space chars between '\' and the first\r
74                                                  * char on the next line are ignored.\r
75                                                  */\r
76                                                 if (ch == '\n') {\r
77                                                         reader.SkipWhitespace ();\r
78                                                         continue;\r
79                                                 }\r
80 \r
81                                                 int escaped = Escape (ch);\r
82                                                 if (escaped == -1) {\r
83                                                         reader.Unread (ch);\r
84                                                         ch = '\\';\r
85                                                 } else {\r
86                                                         ch = escaped;\r
87                                                 }\r
88                                         }\r
89 \r
90                                         idsb.Append((char)ch);\r
91                                 }\r
92                         } else { // ID\r
93                                 while ((ch = reader.Read ()) != -1) {\r
94                                         if (IsIdChar (ch)) {\r
95                                                 idsb.Append ((char) ch);\r
96                                         } else {\r
97                                                 reader.Unread (ch);\r
98                                                 break;\r
99                                         }\r
100                                 }\r
101                         }\r
102                         return idsb.ToString ();\r
103                 }\r
104 \r
105 \r
106 \r
107 \r
108                 /// <summary>\r
109                 /// </summary>\r
110                 /// <param name="ch"></param>\r
111                 /// <returns></returns>\r
112                 public static int Escape (int ch)\r
113                 {\r
114                         int res = -1;\r
115 \r
116                         if (ch >= '0' && ch <='7') {\r
117                                 //TODO : octal code\r
118                         } else {\r
119                                 int id = "abfnrtv\"'\\".IndexOf ((char)ch);\r
120                                 if (id != -1) {\r
121                                         res = "\a\b\f\n\r\t\v\"'\\" [id];\r
122                                 }\r
123                         }\r
124 \r
125                         return res;\r
126                 }\r
127 \r
128         }\r
129 \r
130 \r
131 }\r
132 \r