facf0c92e0
Red Bear OS is a full fork. All sources must be available from git clone with zero network access. Removed gitignore rules that excluded fetched source trees under recipes/*/source/, local/recipes/kde/*/source/, local/recipes/qt/*/source/, and vendor source trees. Build artifacts (target/, build/, source.tar, *.o, *.so) remain excluded. 127291 files added — kernel, relibc, base, bootloader, pkgar, all KDE/Qt frameworks, mesa, wayland, DRM drivers, and every other recipe source.
143 lines
4.2 KiB
C
143 lines
4.2 KiB
C
/* Handle quoted segments of a string.
|
|
Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
|
Written by Daiki Ueno <ueno@gnu.org>, 2015.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef _QUOTE_H
|
|
#define _QUOTE_H
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
static void
|
|
scan_quoted (const char *input, size_t length,
|
|
void (* callback) (char quote, const char *quoted,
|
|
size_t quoted_length,
|
|
void *data),
|
|
void *data)
|
|
{
|
|
const char *p, *start, *end;
|
|
bool seen_opening;
|
|
|
|
/* START shall point to the beginning of a quoted segment, END
|
|
points to the end of the entire input string. */
|
|
start = input;
|
|
end = &input[length - 1];
|
|
|
|
/* True if we have seen a character which could be an opening
|
|
quotation mark. Note that we can't determine if it is really an
|
|
opening quotation mark until we see a closing quotation mark. */
|
|
seen_opening = false;
|
|
|
|
for (p = start; p <= end; p++)
|
|
{
|
|
switch (*p)
|
|
{
|
|
case '"':
|
|
if (seen_opening)
|
|
{
|
|
if (*start == '"')
|
|
{
|
|
if (p == start + 1)
|
|
/* Consider "" as "". */
|
|
callback ('\0', "\"\"", 2, data);
|
|
else
|
|
/* "..." */
|
|
callback ('"', start + 1, p - (start + 1), data);
|
|
|
|
start = p + 1;
|
|
seen_opening = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
callback ('\0', start, p - start, data);
|
|
start = p;
|
|
seen_opening = true;
|
|
}
|
|
break;
|
|
|
|
case '`':
|
|
if (seen_opening)
|
|
{
|
|
if (*start == '`')
|
|
{
|
|
callback ('\0', start, p - start, data);
|
|
start = p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
callback ('\0', start, p - start, data);
|
|
start = p;
|
|
seen_opening = true;
|
|
}
|
|
break;
|
|
|
|
case '\'':
|
|
if (seen_opening)
|
|
{
|
|
if (/* `...' */
|
|
*start == '`'
|
|
/* '...', where
|
|
- The left quote is preceded by a space, and the
|
|
right quote is followed by a space.
|
|
- The left quote is preceded by a space, and the
|
|
right quote is at the end of line.
|
|
- The left quote is at the beginning of the line, and
|
|
the right quote is followed by a space. */
|
|
|| (*start == '\''
|
|
&& (((start > input && *(start - 1) == ' ')
|
|
&& (p == end || *(p + 1) == '\n' || *(p + 1) == ' '))
|
|
|| ((start == input || *(start - 1) == '\n')
|
|
&& p < end && *(p + 1) == ' '))))
|
|
{
|
|
callback ('\'', start + 1, p - (start + 1), data);
|
|
start = p + 1;
|
|
}
|
|
else
|
|
{
|
|
callback ('\0', start, p - start, data);
|
|
start = p;
|
|
}
|
|
seen_opening = false;
|
|
}
|
|
else if (p == input || *(p - 1) == '\n' || *(p - 1) == ' ')
|
|
{
|
|
callback ('\0', start, p - start, data);
|
|
start = p;
|
|
seen_opening = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Copy the rest. */
|
|
if (p > start)
|
|
callback ('\0', start, p - start, data);
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif /* _QUOTE_H */
|