Skip to content

Commit 4209374

Browse files
committed
Implements adeharo9#9
1 parent 231246d commit 4209374

2 files changed

Lines changed: 73 additions & 13 deletions

File tree

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# cpp-dotenv
22

3-
![version 0.1.0](https://img.shields.io/badge/version-0.1.0-blue)
3+
![version 0.2.0](https://img.shields.io/badge/version-0.2.0-blue)
44

55
C++ implementation of NodeJS [dotenv](https://github.com/motdotla/dotenv) project. Loads environment variables from `.env` for C++ projects.
66

@@ -186,4 +186,3 @@ For the geeks, you can check the grammar I've implemented on the `grammar/env.g4
186186
The complete list of issues con be consulted at the [issues page](https://github.com/adeharo9/cpp-dotenv/issues).
187187

188188
1. [Variable resolution on values not yet vailable](https://github.com/adeharo9/cpp-dotenv/issues/3)
189-
2. Scaped sequences not being scaped inside strings

dotenv.h

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <vector>
99

1010

11-
#ifdef _DEBUG
11+
#if defined(_DEBUG) || defined(__DEBUG)
1212
#include <iostream>
1313

1414
#define DEBUG_ENTER(x) std::cerr << "ENTER " << row_count << ":" << col_count << " " << #x << std::endl
@@ -255,33 +255,59 @@ namespace dotenv
255255
inline void SINGLE_UNQUOTED_STRING()
256256
{
257257
DEBUG_ENTER(SINGLE_UNQUOTED_STRING);
258-
while (not token_is(SQ_C)) { next(); }
258+
while (not token_is(SQ_C))
259+
{
260+
if (token_is(BS_C))
261+
{
262+
possible_escaped_sequence();
263+
}
264+
else
265+
{
266+
next();
267+
}
268+
}
259269
DEBUG_EXIT(SINGLE_UNQUOTED_STRING);
260270
}
261271

262272
inline void DOUBLE_UNQUOTED_STRING()
263273
{
264274
DEBUG_ENTER(DOUBLE_UNQUOTED_STRING);
265-
while (not token_is(DQ_C)) { next(); }
275+
while (not token_is(DQ_C))
276+
{
277+
if (token_is(BS_C))
278+
{
279+
possible_escaped_sequence();
280+
}
281+
else
282+
{
283+
next();
284+
}
285+
}
266286
DEBUG_EXIT(DOUBLE_UNQUOTED_STRING);
267287
}
268288

269289
inline void UNQUOTED_KEY()
270290
{
291+
DEBUG_ENTER(UNQUOTED_KEY);
271292
match(UNQUOTED_KEY_CHAR);
272293
while (token_is(UNQUOTED_KEY_CHAR)) { match(UNQUOTED_KEY_CHAR); }
294+
DEBUG_EXIT(UNQUOTED_KEY);
273295
}
274296

275297
inline void UNQUOTED_VALUE()
276298
{
299+
DEBUG_ENTER(UNQUOTED_VALUE);
277300
match(UNQUOTED_VALUE_CHAR);
278301
while (token_is(UNQUOTED_VALUE_CHAR)) { match(UNQUOTED_VALUE_CHAR); }
302+
DEBUG_EXIT(UNQUOTED_VALUE);
279303
}
280304

281305
inline void UNQUOTED_COMMENT()
282306
{
307+
DEBUG_ENTER(UNQUOTED_COMMENT);
283308
match(UNQUOTED_COMMENT_CHAR);
284309
while (token_is(UNQUOTED_COMMENT_CHAR)) { match(UNQUOTED_COMMENT_CHAR); }
310+
DEBUG_EXIT(UNQUOTED_COMMENT);
285311
}
286312

287313
inline void NL()
@@ -290,6 +316,24 @@ namespace dotenv
290316
match(NL_C);
291317
}
292318

319+
inline void possible_escaped_sequence()
320+
{
321+
match(BS_C);
322+
for (auto& equivalence: ESCAPED_EQUIVALENCES)
323+
{
324+
if (equivalence.first == token)
325+
{
326+
if (bond and binded != nullptr) { binded -> pop_back(); }
327+
else if (bond and binded == nullptr) { throw std::runtime_error("something weird happened to this pointer"); }
328+
329+
token = equivalence.second;
330+
next();
331+
332+
break;
333+
}
334+
}
335+
}
336+
293337
inline void eof()
294338
{
295339
if (not is.eof()) { syntax_err(); }
@@ -382,18 +426,20 @@ namespace dotenv
382426

383427
private:
384428

385-
static const char CS_C = '#';
386-
static const char EQ_C = '=';
387-
static const char SP_C = ' ';
388-
static const char SQ_C = '\'';
389-
static const char DQ_C = '\"';
390-
static const char TB_C = '\t';
391-
static const char NL_C = '\n';
392-
static const char CR_C = '\r';
429+
static const char CS_C = '#'; // Comment (sharp)
430+
static const char EQ_C = '='; // Equal sign
431+
static const char SP_C = ' '; // Space
432+
static const char SQ_C = '\''; // Single quote
433+
static const char DQ_C = '\"'; // Double quote
434+
static const char TB_C = '\t'; // Tabulator
435+
static const char NL_C = '\n'; // Newline
436+
static const char CR_C = '\r'; // Carriage return
437+
static const char BS_C = '\\'; // Backslash
393438
static const container SP;
394439
static const container UNQUOTED_KEY_CHAR;
395440
static const container UNQUOTED_VALUE_CHAR;
396441
static const container UNQUOTED_COMMENT_CHAR;
442+
static const std::vector<std::pair<char, char>> ESCAPED_EQUIVALENCES;
397443

398444
};
399445

@@ -440,6 +486,21 @@ namespace dotenv
440486
CR_C
441487
};
442488

489+
const std::vector<std::pair<char, char>> parser::ESCAPED_EQUIVALENCES
490+
{
491+
{ '?' , '?' },
492+
{ '\'', '\'' },
493+
{ '"' , '"' },
494+
{ '\\', '\\' },
495+
{ 'a' , '\a' },
496+
{ 'b' , '\b' },
497+
{ 'f' , '\f' },
498+
{ 'n' , '\n' },
499+
{ 'r' , '\r' },
500+
{ 't' , '\t' },
501+
{ 'v' , '\v' }
502+
};
503+
443504
class dotenv
444505
{
445506
private:

0 commit comments

Comments
 (0)