42 std::ostringstream message;
50 message <<
" included from " << f->
filePath <<
" line " <<
55 message <<
" included from " <<
cfg_filename <<
" line " <<
57 std::string msg = message.str();
60 fatalf(
"Bungled %s line %d: %s",
70 static int fromFile = 0;
71 static FILE *wordFile =
nullptr;
83 }
else if (*t ==
'\"' || *t ==
'\'') {
85 debugs(3, 8,
"Quoted token found : " << t);
88 while (*t && *t !=
'\"' && *t !=
'\'')
93 if ((wordFile = fopen(fn,
"r")) ==
nullptr) {
99 setmode(fileno(wordFile),
O_TEXT);
109 if (fgets(buf,
sizeof(buf), wordFile) ==
nullptr) {
123 while (*t3 && *t3 !=
'#') {
124 t2 = t3 + strcspn(t3,
w_space);
133 }
while ( *t ==
'#' || !*t );
141 const char *errorStr =
nullptr;
142 const char *errorPos =
nullptr;
143 char quoteChar = *
token;
144 assert(quoteChar ==
'"' || quoteChar ==
'\'');
146 const char *s =
token + 1;
149 while (*s && *s != quoteChar && !errorStr && (
size_t)(d - UnQuoted) <
sizeof(UnQuoted) - 1) {
152 errorStr =
"Unterminated escape sequence";
169 errorStr =
"Unsupported escape sequence";
181 if (*s != quoteChar && !errorStr) {
182 errorStr =
"missing quote char at the end of quoted string";
189 if (!errorStr && *(s + 1) !=
'\0' && !strchr(
w_space "()#", *(s + 1))) {
190 errorStr =
"Expecting space after the end of quoted token";
229 if (!nextToken || *nextToken ==
'\0')
232 nextToken += strspn(nextToken,
w_space);
234 if (*nextToken ==
'#')
244 const char *tokenStart = nextToken;
259 nextToken += strcspn(nextToken, sep);
263 if (*(nextToken+1) && *(nextToken+1) !=
'\r' && *(nextToken+1) !=
'\n') {
265 nextToken += strcspn(nextToken, sep);
267 debugs(3,
DBG_CRITICAL,
"FATAL: Unescaped '\' character in regex pattern: " << tokenStart);
273 if (strncmp(tokenStart,
"parameters", nextToken - tokenStart) == 0)
288 char *
token =
nullptr;
289 if (nextToken - tokenStart) {
291 bool tokenIsNumber =
true;
292 for (
const char *s = tokenStart; s != nextToken; ++s) {
293 const bool isValidChar = isalnum(*s) || strchr(
".,()-=_/:+", *s) ||
294 (tokenIsNumber && *s ==
'%' && (s + 1 == nextToken));
297 tokenIsNumber =
false;
305 debugs(3,
DBG_CRITICAL,
"FATAL: Not alphanumeric character '"<< *s <<
"' in unquoted token " << tokenStart);
315 if (*nextToken !=
'\0' && *nextToken !=
'#') {
340 char *
token =
nullptr;
379 debugs(3,
DBG_CRITICAL,
"FATAL: can't open %s for reading parameters: includes are nested too deeply (>16)!\n" << path);
435 if (
const auto middle = strchr(currentToken,
'=')) {
436 if (middle == currentToken)
438 if (middle + 1 == currentToken + strlen(currentToken))
455 key = value =
nullptr;
467 debugs(3,
DBG_CRITICAL,
"ERROR: Failure while parsing key=value token. Value missing after: " << key);
478 debugs(3,
DBG_CRITICAL,
"FATAL: Can not read regex expression while configuration_includes_quoted_values is enabled");
487std::unique_ptr<RegexPattern>
491 throw TextException(
"Cannot read regex expression while configuration_includes_quoted_values is enabled",
Here());
494 int flags = REG_EXTENDED | REG_NOSUB;
497 const auto flagOrPattern =
token(expectedRegexDescription);
498 if (flagOrPattern.cmp(
"-i") == 0) {
500 pattern =
token(expectedRegexDescription);
501 }
else if (flagOrPattern.cmp(
"+i") == 0) {
503 pattern =
token(expectedRegexDescription);
505 pattern = flagOrPattern;
509 return std::unique_ptr<RegexPattern>(
new RegexPattern(pattern, flags));
522 peerNameTokenDescription,
" as ", name),
Here());
543 bool needQuote =
false;
545 for (
const char *l = s; !needQuote && *l !=
'\0'; ++l )
546 needQuote = !isalnum(*l);
553 for (; *s !=
'\0'; ++s) {
554 if (*s ==
'"' || *s ==
'\\')
581 if (
const auto extractedToken =
NextToken()) {
583 return SBuf(extractedToken);
593 if (strcmp(nextToken, keyword) == 0) {
620 debugs(3, 3,
"Parsing from " << path);
621 if ((
wordFile = fopen(path,
"r")) ==
nullptr) {
642 parseBuffer[0] =
'\0';
645 parsePos = parseBuffer;
646 currentLine = parseBuffer;
661 while (!(
token = nextElement(type))) {
671 const char *pos = parsePos;
static const char * SQUID_ERROR_TOKEN
#define CONFIG_LINE_LIMIT
#define Here()
source code location of the caller
size_t aclParseAclList(ConfigParser &, ACLList **config, const char *label)
const char * cfg_directive
During parsing, the name of the current squid.conf directive being parsed.
char config_input_line[BUFSIZ]
const char * cfg_filename
char * nextElement(TokenType &type)
std::string currentLine
The current line to parse.
std::string filePath
The file path.
FILE * wordFile
Pointer to the file.
char * parse(TokenType &type)
bool getFileLine()
Read the next line from the file.
bool startParse(char *path)
bool isOpen()
True if the configuration file is open.
int lineNo
Current line number.
bool optionalKvPair(char *&key, char *&value)
static const char * CfgLine
The current line to parse.
static TokenType LastTokenType
The type of last parsed element.
static SBuf CurrentLocation()
static char * RegexStrtokFile()
static const char * CfgPos
Pointer to the next element in cfgLine string.
static bool RecognizeQuotedPair_
The next tokens may contain quoted-pair (-escaped) characters.
void rejectDuplicateDirective()
rejects configuration due to a repeated directive
static char * NextQuotedToken()
static enum ConfigParser::ParsingStates KvPairState_
Parsing state while parsing kv-pair tokens.
static char * NextQuotedOrToEol()
ACLList * optionalAclList()
parses an [if [!]<acl>...] construct
std::unique_ptr< RegexPattern > regex(const char *expectedRegexDescription)
extracts and returns a regex (including any optional flags)
static std::queue< char * > CfgLineTokens_
Store the list of tokens for current configuration line.
static bool ParseKvPair_
The next token will be handled as kv-pair token.
static char * NextElement(TokenType &type)
Wrapper method for TokenParse.
static bool RecognizeQuotedValues
configuration_includes_quoted_values in squid.conf
static char * PeekAtToken()
static std::stack< CfgFile * > CfgFiles
The stack of open cfg files.
static bool ParseQuotedOrToEol_
The next tokens will be handled as quoted or to_eol token.
bool skipOptional(const char *keyword)
either extracts the given (optional) token or returns false
void closeDirective()
stops parsing the current configuration directive
static char * UnQuote(const char *token, const char **next=nullptr)
static bool NextKvPair(char *&key, char *&value)
CachePeer & cachePeer(const char *peerNameTokenDescription)
extracts a cache_peer name token and returns the corresponding CachePeer
static void SetCfgLine(char *line)
Set the configuration file line to parse.
static char * NextToken()
static char * strtokFile()
SBuf token(const char *expectedTokenDescription)
extracts and returns a required token
static const char * QuoteString(const String &var)
static char * TokenParse(const char *&nextToken, TokenType &type)
a source code location that is cheap to create, copy, and store
char const * termedBuf() const
void append(char const *buf, int len)
an std::runtime_error with thrower location info
#define debugs(SECTION, LEVEL, CONTENT)
void fatalf(const char *fmt,...)
CachePeer * findCachePeerByName(const char *const name)
cache_peer with a given name (or nil)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
#define LOCAL_ARRAY(type, name, size)
char * xstrncpy(char *dst, const char *src, size_t n)
char * xstrndup(const char *s, size_t n)