

Go to the source code of this file.
Functions | |
| int | cbf_lex (YYSTYPE *val, cbf_file *file) |
Definition at line 162 of file cbf_lex.c.
References BINARY, bits(), CATEGORY, cbf_add_fileconnection(), cbf_cistrcmp(), cbf_delete_fileconnection(), cbf_errornez, CBF_FILEREAD, CBF_FORMAT, cbf_frombase64(), cbf_frombasex(), cbf_fromqp(), cbf_get_buffer(), cbf_get_filecoordinates(), cbf_get_fileposition(), cbf_is_base64digest(), cbf_md5digest(), cbf_nblen(), cbf_parse_binaryheader(), cbf_parse_mimeheader(), cbf_read_character(), cbf_reset_buffer(), cbf_return_text(), cbf_save_character(), cbf_set_fileposition(), CBF_TOKEN_BIN, CBF_TOKEN_DQSTRING, CBF_TOKEN_MIME_BIN, CBF_TOKEN_NULL, CBF_TOKEN_SCSTRING, CBF_TOKEN_SQSTRING, CBF_TOKEN_WORD, COLUMN, COMMENT, cbf_compress_nodestruct::count, DATA, ENC_BASE10, ENC_BASE16, ENC_BASE64, ENC_BASE8, ENC_NONE, ENC_QP, ERROR, YYSTYPE::errorcode, ITEM, cbf_file::last_read, LOOP, MSG_DIGESTNOW, cbf_file::read_headers, STRING, and WORD.
Referenced by cbf_lex_wrapper().
{
int data, loop, item, column, comment, string, ascii,
l, c, count, reprocess, errorcode, mime, encoding, bits, sign,
checked_digest;
long id, position;
unsigned int file_column, compression;
size_t size, length, code_size;
const char *line;
char out_line [(((sizeof (void *) +
sizeof (long int) * 2 +
sizeof (int) * 3) * CHAR_BIT) >> 2) + 55];
char digest [25], new_digest [25];
cbf_errornez (cbf_reset_buffer (file), val)
l = c = file->last_read;
column = c == '.';
comment = c == '#';
reprocess = (column || comment);
data = loop = item = string = !reprocess;
comment = !column;
do
{
cbf_errornez (cbf_get_buffer (file, &line, &length), val)
if (reprocess)
reprocess = 0;
else
{
l = c;
c = cbf_read_character (file);
}
/* Discard spaces ([[:space:]]+) */
if (length == 0)
if (isspace (c))
continue;
/* DATA ([Dd][Aa][Tt][Aa][_][^[:space:]]*) */
if (data)
if (length < 5)
data = toupper (c) == "DATA_" [length];
else
if (isspace (c) || c == EOF)
return cbf_return_text (DATA, val, &line [5], 0);
/* LOOP ([Ll][Oo][Oo][Pp][_]) */
if (loop)
{
loop = toupper (c) == "LOOP_" [length];
if (loop && length == 4)
return LOOP;
}
/* ITEM ([_][^[:space:]\.]+) */
if (item)
if (length == 0)
item = c == '_';
else
{
item = !isspace (c) && c != '.' && c != '#' && c != EOF;
if (length >= 2 && !item)
if (c == '.')
return cbf_return_text (CATEGORY, val, &line [1], 0);
else
return cbf_return_text (ITEM, val, &line [1], 0);
}
/* COLUMN (\.[^[:space:]]+) */
if (column)
if (isspace (c) || c == EOF)
return cbf_return_text (COLUMN, val, &line [1], 0);
/* STRING ([\'][^'\n]*[\'\n])|(([\"][^"\n]*[\"\n])) */
if (string)
if (length == 0)
string = c == '\'' || c == '"';
else
if (c == line [0] || c == '\n' || c == EOF)
if (line [0] == '\'')
return cbf_return_text (STRING, val, &line [1],
CBF_TOKEN_SQSTRING);
else
return cbf_return_text (STRING, val, &line [1],
CBF_TOKEN_DQSTRING);
/* COMMENT ([#][^\n]*) */
if (comment)
if (length == 0)
comment = c == '#';
else
if (c == '\n' || c == EOF)
return cbf_return_text (COMMENT, val, &line [1], 0);
/* WORD ([^[:space:]]+) */
if (!data && !loop && !item && !comment && !string && !column)
if (length && (isspace (c) || c == EOF))
/* Missing value? */
if (length == 1 && (line [0] == '?' || line [0] == '.'))
return cbf_return_text (WORD, val, &line [0], CBF_TOKEN_NULL);
else
return cbf_return_text (WORD, val, &line [0], CBF_TOKEN_WORD);
/* semicolon-delimited STRING (^;[^\n]*[\n])([^;][^\n]*[\n])*(;) */
if (length == 0 && c == ';')
{
cbf_errornez (cbf_get_filecoordinates (file, NULL, &file_column), val)
if (file_column == 1)
{
/* Save the position */
cbf_errornez (cbf_get_fileposition (file, &position), val)
mime = 0;
do
{
/* Save the character */
cbf_errornez (cbf_save_character (file, c), val)
/* Check for a Mime boundary */
if (c == '-')
{
cbf_errornez (cbf_get_buffer (file, &line, &length), val)
cbf_nblen (line, &length);
if (length > 29)
mime = cbf_cistrcmp (&line [length - 30],
"\n--CIF-BINARY-FORMAT-SECTION--")
== 0;
}
/* Read the next character */
l = c;
c = cbf_read_character (file);
ascii = isgraph (c) || isspace (c);
}
while ((l != '\n' || c != ';') && !mime && ascii);
/* Plain ASCII string */
if (!mime && ascii)
{
cbf_errornez (cbf_get_buffer (file, &line, &length), val)
((char *) line) [length - 1] = '\0';
/* Convert "\n\\;" -> "\n;" */
for (count = 0; line [count]; count++)
if (strncmp (&line [count], "\n\\;", 3) == 0)
memmove ((void *) &line [count + 1],
(void *) &line [count + 2], length - count - 2);
return cbf_return_text (STRING, val, &line [1],
CBF_TOKEN_SCSTRING);
}
encoding = ENC_NONE;
bits = 0;
sign = -1;
checked_digest = 0;
/* Mime header */
if (mime)
{
/* Position */
cbf_errornez (cbf_get_fileposition (file, &position), val)
/* Read the header */
cbf_errornez (cbf_parse_mimeheader (file, &encoding,
&size,
&id,
digest,
&compression,
&bits,
&sign), val)
/* Check the digest? */
if ((file->read_headers & MSG_DIGESTNOW) &&
cbf_is_base64digest (digest))
{
/* Recalculate the digest (note that this will decode the
binary section but not save the result so this section
is not very efficient) */
code_size = 0;
switch (encoding)
{
case ENC_QP:
cbf_errornez (cbf_fromqp (file, NULL, size, &code_size,
new_digest), val)
break;
case ENC_BASE64:
cbf_errornez (cbf_frombase64 (file, NULL, size, &code_size,
new_digest), val)
break;
case ENC_BASE8:
case ENC_BASE10:
case ENC_BASE16:
cbf_errornez (cbf_frombasex (file, NULL, size, &code_size,
new_digest),val)
break;
case ENC_NONE:
cbf_errornez (cbf_parse_binaryheader (file, NULL, \
NULL, \
NULL, \
mime), val)
code_size = size;
cbf_errornez (cbf_get_fileposition (file, &position), val)
cbf_errornez (cbf_md5digest (file, code_size, new_digest),
val)
break;
default:
cbf_errornez (CBF_FORMAT, val)
}
/* Check the number of characters read */
if ((size && (size != code_size)) || code_size == 0)
cbf_errornez (CBF_FORMAT, val)
/* Compare the old digest to the new one */
if (strcmp (digest, new_digest) != 0)
cbf_errornez (CBF_FORMAT | 2, val)
checked_digest = 1;
}
else
{
/* Calculate the minimum number of characters in the data */
if (encoding == ENC_NONE)
{
cbf_errornez (cbf_parse_binaryheader (file, NULL, NULL, NULL, \
mime), val)
cbf_errornez (cbf_get_fileposition (file, &position), val)
code_size = size;
}
else
if (encoding == ENC_QP)
code_size = size;
else
if (encoding == ENC_BASE64)
code_size = size * 8 / 6;
else
code_size = size / 4;
/* Skip to the end of the data */
cbf_errornez (cbf_set_fileposition (file, code_size, SEEK_CUR),
val)
}
}
else
{
/* Simple binary */
cbf_errornez (cbf_parse_binaryheader (file, &size, \
&id, \
&compression, mime), val)
cbf_errornez (cbf_get_fileposition (file, &position), val)
code_size = size;
/* Skip to the end of the data */
cbf_errornez (cbf_set_fileposition (file, code_size, SEEK_CUR), val)
}
/* Find the terminating semi-colon */
c = 0;
do
{
l = c;
c = cbf_read_character (file);
if (c == EOF)
cbf_errornez (CBF_FILEREAD, val)
}
while (l != '\n' || c != ';');
/* Check the element size and sign */
if (bits < 0 || bits > 64)
cbf_errornez (CBF_FORMAT, val)
if (bits == 0)
bits = 32;
if (sign == -1)
sign = 1;
/* Add a connection */
cbf_errornez (cbf_add_fileconnection (&file, NULL), val)
/* Code the id, file, position, size and digest */
if (!cbf_is_base64digest (digest))
strcpy (digest, "------------------------");
sprintf (out_line, "%x %p %lx %lx %d %s %x %d %u",
id, file, position, size, checked_digest,
digest, bits, sign, compression);
if (encoding == ENC_NONE)
errorcode = cbf_return_text (BINARY, val, out_line,
CBF_TOKEN_BIN);
else
errorcode = cbf_return_text (BINARY, val, out_line,
CBF_TOKEN_MIME_BIN);
if (errorcode == ERROR)
val->errorcode |= cbf_delete_fileconnection (&file);
return errorcode;
}
}
/* Add the character to the text */
errorcode = cbf_save_character (file, c);
cbf_errornez (errorcode, val);
}
while (c != EOF);
return 0;
}
1.7.3