Code

sysdb: Use the flex scanner generator for reading input.
[sysdb.git] / src / tools / sysdb / input.c
1 /*
2  * SysDB - src/tools/sysdb/input.c
3  * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #if HAVE_CONFIG_H
29 #       include "config.h"
30 #endif /* HAVE_CONFIG_H */
32 #include "tools/sysdb/input.h"
34 #include "utils/strbuf.h"
36 #include <stdio.h>
37 #include <stdlib.h>
39 #include <string.h>
41 #if HAVE_EDITLINE_READLINE_H
42 #       include <editline/readline.h>
43 #       if HAVE_EDITLINE_HISTORY_H
44 #               include <editline/history.h>
45 #       endif
46 #elif HAVE_READLINE_READLINE_H
47 #       include <readline/readline.h>
48 #       if HAVE_READLINE_HISTORY_H
49 #               include <readline/history.h>
50 #       endif
51 #elif HAVE_READLINE_H
52 #       include <readline.h>
53 #       if HAVE_HISTORY_H
54 #               include <history.h>
55 #       endif
56 #endif /* READLINEs */
58 /*
59  * private helper functions
60  */
62 static size_t
63 input_readline(sdb_strbuf_t *buf)
64 {
65         const char *prompt = "sysdb=> ";
66         char *line;
68         size_t len;
70         if (sdb_strbuf_len(buf))
71                 prompt = "sysdb-> ";
73         line = readline(prompt);
75         if (! line)
76                 return 0;
78         len = strlen(line);
80         sdb_strbuf_append(buf, line);
81         free(line);
82         return len;
83 } /* input_readline */
85 /*
86  * API
87  */
89 ssize_t
90 sdb_input_readline(sdb_input_t *input, char *buf,
91                 int *n_chars, size_t max_chars)
92 {
93         const char *query;
94         size_t buflen, len;
96         buflen = sdb_strbuf_len(input->buf);
97         len = buflen - input->tokenizer_pos;
99         if (! len) {
100                 size_t n = input_readline(input->buf);
101                 if (! n) {
102                         *n_chars = 0; /* YY_NULL */
103                         return 0;
104                 }
105                 buflen += n;
106                 len += n;
107         }
109         query = sdb_strbuf_string(input->buf);
111         len = (len < max_chars) ? len : max_chars;
112         strncpy(buf, sdb_strbuf_string(input->buf) + input->tokenizer_pos, len);
113         input->tokenizer_pos += len;
114         *n_chars = (int)len;
116         /* XXX */
117         if (! strchr(query, (int)';'))
118                 return (ssize_t)len;
119         sdb_strbuf_clear(input->buf);
120         input->tokenizer_pos = 0;
121         return (ssize_t)len;
122 } /* sdb_input_readline */
124 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */