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; }