summaryrefslogtreecommitdiff
path: root/paragraph.c
diff options
context:
space:
mode:
authorAntti-Juhani Kaijanaho <ajk@debian.org>2006-01-28 21:10:55 +0100
committerAntti-Juhani Kaijanaho <ajk@debian.org>2006-01-28 21:10:55 +0100
commit4c90b78306e1334e1bd6dcb105d9bb4d5f53a845 (patch)
tree65b3c9e54508bd4f800ae6caed260c85a29248ce /paragraph.c
downloaddctrl-tools-4c90b78306e1334e1bd6dcb105d9bb4d5f53a845.tar.gz
Import 1.100
Diffstat (limited to 'paragraph.c')
-rw-r--r--paragraph.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/paragraph.c b/paragraph.c
new file mode 100644
index 0000000..a6d1145
--- /dev/null
+++ b/paragraph.c
@@ -0,0 +1,135 @@
+/* dctrl-tools - Debian control file inspection tools
+ Copyright (C) 2003 Antti-Juhani Kaijanaho
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "msg.h"
+#include "paragraph.h"
+
+void para_init(para_t * para, FSAF * fp, fieldtrie_t * trie)
+{
+ para->fp = fp;
+ para->trie = trie;
+ para->start = 0;
+ para->end = 0;
+ para->eof = false;
+ para_parse_next(para);
+}
+
+void para_parse_next(para_t * para)
+{
+ debug_message("para_parse_next", 0);
+ para->start = para->end;
+ fsaf_invalidate(para->fp, para->start);
+ register enum { START, FIELD_NAME, BODY, BODY_NEWLINE,
+ BODY_SKIPBLANKS, END } state = START;
+ register size_t pos = para->start;
+ register FSAF * fp = para->fp;
+ size_t field_start = 0;
+ struct field_data * field_data = 0;
+ while (state != END) {
+ int c = fsaf_getc(fp, pos++);
+ switch (state) {
+ case START:
+ switch (c) {
+ case -1:
+ para->eof = true;
+ state = END;
+ break;
+ case '\n':
+ para->start++;
+ break;
+ default:
+ field_start = --pos;
+ state = FIELD_NAME;
+ }
+ break;
+ case FIELD_NAME:
+ switch (c) {
+ case -1:
+ message(L_FATAL, "unexpected end of file", 0);
+ exit(EXIT_FAILURE);
+ case ':': {
+ size_t len = (pos-1) - field_start;
+ struct fsaf_read_rv r = fsaf_read(fp, field_start, len);
+ assert(r.len == len);
+ size_t inx = fieldtrie_lookup(para->trie, r.b, len);
+ if (inx == -1) {
+ field_data = 0;
+ } else {
+ assert(inx < MAX_FIELDS);
+ field_data = &para->fields[inx];
+ field_data->start = pos;
+ }
+ state = BODY;
+ }
+ break;
+ case '\n':
+ message(L_FATAL, "unexpected end of line", 0);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case BODY:
+ switch (c) {
+ case -1:
+ message(L_FATAL, "unexpected end of file", 0);
+ exit(EXIT_FAILURE);
+ case '\n':
+ if (field_data != 0) {
+ field_data->end = pos-1;
+ while (field_data->start < field_data->end
+ && fsaf_getc(fp, field_data->start) == ' ') {
+ ++field_data->start;
+ }
+ }
+ state = BODY_NEWLINE;
+ break;
+ }
+ break;
+ case BODY_NEWLINE:
+ switch (c) {
+ case -1:
+ para->eof = true;
+ /* pass through */
+ case '\n':
+ state = END;
+ break;
+ case ' ': case '\t':
+ state = BODY_SKIPBLANKS;
+ break;
+ default:
+ field_start = --pos;
+ state = FIELD_NAME;
+ }
+ break;
+ case BODY_SKIPBLANKS:
+ switch (c) {
+ case -1:
+ /* pass through */
+ case '\n':
+ state = END;
+ break;
+ case ' ': case '\t':
+ break;
+ default:
+ state = BODY;
+ }
+ break;
+ case END: assert(0);
+ }
+ }
+ para->end = pos-1;
+}