Skip to content

Commit 9581a34

Browse files
committed
add support for single quoted strings
see #6
1 parent 1226f84 commit 9581a34

23 files changed

Lines changed: 166 additions & 49 deletions

Hjson/BaseReader.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,17 +200,30 @@ public JsonValue ReadNumericLiteral()
200200
else return val;
201201
}
202202

203-
public string ReadStringLiteral()
203+
public string ReadStringLiteral(Func<string> allowML)
204204
{
205-
if (PeekChar()!='"') throw ParseError("Invalid JSON string literal format");
205+
// callers make sure that (exitCh == '"' || exitCh == "'")
206206

207-
ReadChar();
207+
int exitCh=ReadChar();
208208
sb.Length=0;
209209
for (; ; )
210210
{
211211
int c=ReadChar();
212212
if (c<0) throw ParseError("JSON string is not closed");
213-
if (c=='"') return sb.ToString();
213+
if (c==exitCh)
214+
{
215+
if (allowML!=null && exitCh=='\'' && PeekChar()=='\'' && sb.Length==0)
216+
{
217+
// ''' indicates a multiline string
218+
ReadChar();
219+
return allowML();
220+
}
221+
else return sb.ToString();
222+
}
223+
else if (c=='\n' || c=='\r')
224+
{
225+
throw ParseError("Bad string containing newline");
226+
}
214227
else if (c!='\\')
215228
{
216229
sb.Append((char)c);
@@ -224,6 +237,7 @@ public string ReadStringLiteral()
224237
switch (c)
225238
{
226239
case '"':
240+
case '\'':
227241
case '\\':
228242
case '/': sb.Append((char)c); break;
229243
case 'b': sb.Append('\x8'); break;

Hjson/Hjson.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<VersionPrefix>2.1.4</VersionPrefix>
4+
<VersionPrefix>3.0.0</VersionPrefix>
55
<TargetFramework>netstandard1.3</TargetFramework>
66
<GenerateDocumentationFile>true</GenerateDocumentationFile>
77
<AssemblyName>Hjson</AssemblyName>

Hjson/HjsonReader.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ JsonValue ReadCore(bool objectWithoutBraces=false)
168168
if (ReadWsc) { wsc.Comments[name]=GetWhite(); wsc.Order.Add(name); }
169169
}
170170
return obj;
171-
case '"': return ReadStringLiteral();
171+
case '\'':
172+
case '"': return ReadStringLiteral(readMlString);
172173
default: return readTfnns(c);
173174
}
174175
}
@@ -178,13 +179,14 @@ string readKeyName()
178179
// quotes for keys are optional in Hjson
179180
// unless they include {}[],: or whitespace.
180181

181-
if (PeekChar()=='"') return ReadStringLiteral();
182+
int c=PeekChar();
183+
if (c=='"' || c=='\'') return ReadStringLiteral(null);
182184

183185
sb.Length=0;
184186
int space=-1;
185187
for (; ; )
186188
{
187-
int c=PeekChar();
189+
c=PeekChar();
188190
if (c<0) throw ParseError("Name is not closed");
189191
char ch=(char)c;
190192
if (ch==':')
@@ -218,7 +220,7 @@ void skipIndent(int indent)
218220
}
219221
}
220222

221-
JsonValue readMlString()
223+
string readMlString()
222224
{
223225
// Parse a multiline string value.
224226
int triple=0;
@@ -420,11 +422,7 @@ JsonValue readTfnns(int c)
420422
}
421423
}
422424
ReadChar();
423-
if (c!='\r')
424-
{
425-
sb.Append((char)c);
426-
if (sb.Length==3 && sb[0]=='\'' && sb[1]=='\'' && sb[2]=='\'') return readMlString();
427-
}
425+
if (c!='\r') sb.Append((char)c);
428426
c=PeekChar();
429427
}
430428
}

Hjson/HjsonWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal class HjsonWriter
1616
bool writeWsc;
1717
bool emitRootBraces;
1818
IEnumerable<IHjsonDsfProvider> dsfProviders=Enumerable.Empty<IHjsonDsfProvider>();
19-
static Regex needsEscapeName=new Regex(@"[,\{\[\}\]\s:#""]|\/\/|\/\*|'''");
19+
static Regex needsEscapeName=new Regex(@"[,\{\[\}\]\s:#""']|\/\/|\/\*|'''");
2020

2121
public HjsonWriter(HjsonOptions options)
2222
{
@@ -172,8 +172,8 @@ void writeString(string value, TextWriter tw, int level, bool hasComment, string
172172
if (doEscape ||
173173
BaseReader.IsWhite(left) || BaseReader.IsWhite(right) ||
174174
left=='"' ||
175+
left=='\'' ||
175176
left=='#' ||
176-
left=='\'' && left1=='\'' && left2=='\'' ||
177177
left=='/' && (left1=='*' || left1=='/') ||
178178
HjsonValue.IsPunctuatorChar(left) ||
179179
HjsonReader.TryParseNumericLiteral(value, true, out dummy) ||

Hjson/JsonReader.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ JsonValue ReadCore()
6363
for (; ; )
6464
{
6565
if (SkipPeekChar()=='}') { ReadChar(); break; }
66-
string name=ReadStringLiteral();
66+
if (PeekChar()!='"') throw ParseError("Invalid JSON string literal format");
67+
string name=ReadStringLiteral(null);
6768
SkipWhite();
6869
Expect(':');
6970
SkipWhite();
@@ -87,7 +88,7 @@ JsonValue ReadCore()
8788
Expect("null");
8889
return (JsonValue)null;
8990
case '"':
90-
return ReadStringLiteral();
91+
return ReadStringLiteral(null);
9192
default:
9293
if (c>='0' && c<='9' || c=='-')
9394
return ReadNumericLiteral();

Hjson/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
[assembly: System.Reflection.AssemblyDescription("Hjson.dll")]
33
[assembly: System.Reflection.AssemblyProduct("Hjson - https://github.com/hjson/hjson-cs")]
44
[assembly: System.Reflection.AssemblyCopyright("See LICENSE")]
5-
[assembly: System.Reflection.AssemblyFileVersion("2.1.4.0")]
5+
[assembly: System.Reflection.AssemblyFileVersion("3.0.0.0")]
66
[assembly: System.Reflection.AssemblyTitle("Hjson.dll")]
77
[assembly: System.CLSCompliant(true)]

history.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# hjson-cs History
22

3+
- v3.0.0
4+
- add support for single quoted strings
35
- v2.1.3
46
- Update ML stringify to match JS
57
- v2.1.2

test/assets/charset_test.hjson

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
ql-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
2-
js-ascii: "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
3-
ml-ascii:
4-
'''
5-
! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
6-
'''
1+
{
2+
ql-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
3+
js-ascii: "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
4+
ml-ascii:
5+
'''
6+
! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
7+
'''
8+
}

test/assets/failJSON24_test.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/assets/failKey5_test.hjson

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
# invalid name
3+
'''foo''': 0
4+
}

0 commit comments

Comments
 (0)