xref: /freebsd/contrib/bc/include/file.h (revision d101cdd6edd782f6ec56eef63ed91abd77a8b317)
1252884aeSStefan Eßer /*
2252884aeSStefan Eßer  * *****************************************************************************
3252884aeSStefan Eßer  *
43aa99676SStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
5252884aeSStefan Eßer  *
6*d101cdd6SStefan Eßer  * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
7252884aeSStefan Eßer  *
8252884aeSStefan Eßer  * Redistribution and use in source and binary forms, with or without
9252884aeSStefan Eßer  * modification, are permitted provided that the following conditions are met:
10252884aeSStefan Eßer  *
11252884aeSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
12252884aeSStefan Eßer  *   list of conditions and the following disclaimer.
13252884aeSStefan Eßer  *
14252884aeSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
15252884aeSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
16252884aeSStefan Eßer  *   and/or other materials provided with the distribution.
17252884aeSStefan Eßer  *
18252884aeSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19252884aeSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20252884aeSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21252884aeSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22252884aeSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23252884aeSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24252884aeSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25252884aeSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26252884aeSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27252884aeSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28252884aeSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
29252884aeSStefan Eßer  *
30252884aeSStefan Eßer  * *****************************************************************************
31252884aeSStefan Eßer  *
32252884aeSStefan Eßer  * Definitions for implementing buffered I/O on my own terms.
33252884aeSStefan Eßer  *
34252884aeSStefan Eßer  */
35252884aeSStefan Eßer 
36252884aeSStefan Eßer #ifndef BC_FILE_H
37252884aeSStefan Eßer #define BC_FILE_H
38252884aeSStefan Eßer 
39252884aeSStefan Eßer #include <stdarg.h>
40252884aeSStefan Eßer 
4178bc019dSStefan Eßer #include <history.h>
42252884aeSStefan Eßer #include <vector.h>
43252884aeSStefan Eßer 
44252884aeSStefan Eßer #define BC_FILE_ULL_LENGTH (21)
45252884aeSStefan Eßer 
4678bc019dSStefan Eßer #if BC_ENABLE_LINE_LIB
47252884aeSStefan Eßer 
4878bc019dSStefan Eßer #include <stdio.h>
4978bc019dSStefan Eßer 
5078bc019dSStefan Eßer /// The file struct.
5178bc019dSStefan Eßer typedef struct BcFile
5278bc019dSStefan Eßer {
5378bc019dSStefan Eßer 	// The file. This is here simply to make the line lib code as compatible
5478bc019dSStefan Eßer 	// with the existing code as possible.
5578bc019dSStefan Eßer 	FILE* f;
5678bc019dSStefan Eßer 
5778bc019dSStefan Eßer } BcFile;
5878bc019dSStefan Eßer 
5978bc019dSStefan Eßer #else // BC_ENABLE_LINE_LIB
6078bc019dSStefan Eßer 
6178bc019dSStefan Eßer /// The file struct.
6278bc019dSStefan Eßer typedef struct BcFile
6378bc019dSStefan Eßer {
6444d4804dSStefan Eßer 	// The actual file descriptor.
65252884aeSStefan Eßer 	int fd;
6644d4804dSStefan Eßer 
6744d4804dSStefan Eßer 	// The buffer for the file.
68252884aeSStefan Eßer 	char* buf;
6944d4804dSStefan Eßer 
7044d4804dSStefan Eßer 	// The length (number of actual chars) in the buffer.
71252884aeSStefan Eßer 	size_t len;
7244d4804dSStefan Eßer 
7344d4804dSStefan Eßer 	// The capacity (max number of chars) of the buffer.
74252884aeSStefan Eßer 	size_t cap;
75252884aeSStefan Eßer 
76252884aeSStefan Eßer } BcFile;
77252884aeSStefan Eßer 
7878bc019dSStefan Eßer #endif // BC_ENABLE_LINE_LIB
7978bc019dSStefan Eßer 
8078bc019dSStefan Eßer #if BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB
8144d4804dSStefan Eßer 
8244d4804dSStefan Eßer /// Types of flushing. These are important because of history and printing
8344d4804dSStefan Eßer /// strings without newlines, something that users could use as their own
8444d4804dSStefan Eßer /// prompts.
8578bc019dSStefan Eßer typedef enum BcFlushType
8678bc019dSStefan Eßer {
8744d4804dSStefan Eßer 	/// Do not clear the stored partial line, but don't add to it.
887e5c51e5SStefan Eßer 	BC_FLUSH_NO_EXTRAS_NO_CLEAR,
8944d4804dSStefan Eßer 
9044d4804dSStefan Eßer 	/// Do not clear the stored partial line and add to it.
917e5c51e5SStefan Eßer 	BC_FLUSH_SAVE_EXTRAS_NO_CLEAR,
9244d4804dSStefan Eßer 
9344d4804dSStefan Eßer 	/// Clear the stored partial line and do not save the new stuff either.
947e5c51e5SStefan Eßer 	BC_FLUSH_NO_EXTRAS_CLEAR,
9544d4804dSStefan Eßer 
9644d4804dSStefan Eßer 	/// Clear the stored partial line, but save the new stuff.
977e5c51e5SStefan Eßer 	BC_FLUSH_SAVE_EXTRAS_CLEAR,
987e5c51e5SStefan Eßer 
997e5c51e5SStefan Eßer } BcFlushType;
10044d4804dSStefan Eßer 
101*d101cdd6SStefan Eßer // These are here to satisfy a clang warning about recursive macros.
102*d101cdd6SStefan Eßer 
103*d101cdd6SStefan Eßer #define bc_file_putchar(f, t, c) bc_file_putchar_impl(f, t, c)
104*d101cdd6SStefan Eßer #define bc_file_flushErr(f, t) bc_file_flushErr_impl(f, t)
105*d101cdd6SStefan Eßer #define bc_file_flush(f, t) bc_file_flush_impl(f, t)
106*d101cdd6SStefan Eßer #define bc_file_write(f, t, b, n) bc_file_write_impl(f, t, b, n)
107*d101cdd6SStefan Eßer #define bc_file_puts(f, t, s) bc_file_puts_impl(f, t, s)
108*d101cdd6SStefan Eßer 
10978bc019dSStefan Eßer #else // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB
11044d4804dSStefan Eßer 
11144d4804dSStefan Eßer // These make sure that the BcFlushType parameter disappears if history is not
11278bc019dSStefan Eßer // used, editline is used, or readline is used.
11344d4804dSStefan Eßer 
114*d101cdd6SStefan Eßer #define bc_file_putchar(f, t, c) bc_file_putchar_impl(f, c)
115*d101cdd6SStefan Eßer #define bc_file_flushErr(f, t) bc_file_flushErr_impl(f)
116*d101cdd6SStefan Eßer #define bc_file_flush(f, t) bc_file_flush_impl(f)
117*d101cdd6SStefan Eßer #define bc_file_write(f, t, b, n) bc_file_write_impl(f, b, n)
118*d101cdd6SStefan Eßer #define bc_file_puts(f, t, s) bc_file_puts_impl(f, s)
11944d4804dSStefan Eßer 
12078bc019dSStefan Eßer #endif // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB
12178bc019dSStefan Eßer 
12278bc019dSStefan Eßer #if BC_ENABLE_LINE_LIB
12378bc019dSStefan Eßer 
12478bc019dSStefan Eßer /**
12578bc019dSStefan Eßer  * Initialize a file.
12678bc019dSStefan Eßer  * @param f     The file to initialize.
12778bc019dSStefan Eßer  * @param file  The stdio file.
12878bc019dSStefan Eßer  */
12978bc019dSStefan Eßer void
13078bc019dSStefan Eßer bc_file_init(BcFile* f, FILE* file);
13178bc019dSStefan Eßer 
13278bc019dSStefan Eßer #else // BC_ENABLE_LINE_LIB
1337e5c51e5SStefan Eßer 
13444d4804dSStefan Eßer /**
13544d4804dSStefan Eßer  * Initialize a file.
13644d4804dSStefan Eßer  * @param f    The file to initialize.
13744d4804dSStefan Eßer  * @param fd   The file descriptor.
13844d4804dSStefan Eßer  * @param buf  The buffer for the file.
13944d4804dSStefan Eßer  * @param cap  The capacity of the buffer.
14044d4804dSStefan Eßer  */
14178bc019dSStefan Eßer void
14278bc019dSStefan Eßer bc_file_init(BcFile* f, int fd, char* buf, size_t cap);
14378bc019dSStefan Eßer 
14478bc019dSStefan Eßer #endif // BC_ENABLE_LINE_LIB
14544d4804dSStefan Eßer 
14644d4804dSStefan Eßer /**
14744d4804dSStefan Eßer  * Frees a file, including flushing it.
14844d4804dSStefan Eßer  * @param f  The file to free.
14944d4804dSStefan Eßer  */
15078bc019dSStefan Eßer void
15178bc019dSStefan Eßer bc_file_free(BcFile* f);
152252884aeSStefan Eßer 
15344d4804dSStefan Eßer /**
15444d4804dSStefan Eßer  * Print a char into the file.
15544d4804dSStefan Eßer  * @param f     The file to print to.
15644d4804dSStefan Eßer  * @param type  The flush type.
15744d4804dSStefan Eßer  * @param c     The character to write.
15844d4804dSStefan Eßer  */
15978bc019dSStefan Eßer void
16078bc019dSStefan Eßer bc_file_putchar(BcFile* restrict f, BcFlushType type, uchar c);
16144d4804dSStefan Eßer 
16244d4804dSStefan Eßer /**
16344d4804dSStefan Eßer  * Flush and return an error if it failed. This is meant to be used when needing
16444d4804dSStefan Eßer  * to flush in error situations when an error is already in flight. It would be
16544d4804dSStefan Eßer  * a very bad deal to throw another error.
16644d4804dSStefan Eßer  * @param f     The file to flush.
16744d4804dSStefan Eßer  * @param type  The flush type.
16844d4804dSStefan Eßer  * @return      A status indicating if an error occurred.
16944d4804dSStefan Eßer  */
17078bc019dSStefan Eßer BcStatus
17178bc019dSStefan Eßer bc_file_flushErr(BcFile* restrict f, BcFlushType type);
17244d4804dSStefan Eßer 
17344d4804dSStefan Eßer /**
17444d4804dSStefan Eßer  * Flush and throw an error on failure.
17544d4804dSStefan Eßer  * @param f     The file to flush.
17644d4804dSStefan Eßer  * @param type  The flush type.
17744d4804dSStefan Eßer  */
17878bc019dSStefan Eßer void
17978bc019dSStefan Eßer bc_file_flush(BcFile* restrict f, BcFlushType type);
18044d4804dSStefan Eßer 
18144d4804dSStefan Eßer /**
18244d4804dSStefan Eßer  * Write the contents of buf to the file.
18344d4804dSStefan Eßer  * @param f     The file to flush.
18444d4804dSStefan Eßer  * @param type  The flush type.
18544d4804dSStefan Eßer  * @param buf   The buffer whose contents will be written to the file.
18644d4804dSStefan Eßer  * @param n     The length of buf.
18744d4804dSStefan Eßer  */
18878bc019dSStefan Eßer void
18978bc019dSStefan Eßer bc_file_write(BcFile* restrict f, BcFlushType type, const char* buf, size_t n);
19044d4804dSStefan Eßer 
19144d4804dSStefan Eßer /**
19244d4804dSStefan Eßer  * Write to the file like fprintf would. This is very rudimentary.
19344d4804dSStefan Eßer  * @param f    The file to flush.
19444d4804dSStefan Eßer  * @param fmt  The format string.
19544d4804dSStefan Eßer  */
19678bc019dSStefan Eßer void
19778bc019dSStefan Eßer bc_file_printf(BcFile* restrict f, const char* fmt, ...);
19844d4804dSStefan Eßer 
19944d4804dSStefan Eßer /**
20044d4804dSStefan Eßer  * Write to the file like vfprintf would. This is very rudimentary.
20144d4804dSStefan Eßer  * @param f    The file to flush.
20244d4804dSStefan Eßer  * @param fmt  The format string.
20344d4804dSStefan Eßer  */
20478bc019dSStefan Eßer void
20578bc019dSStefan Eßer bc_file_vprintf(BcFile* restrict f, const char* fmt, va_list args);
20644d4804dSStefan Eßer 
20744d4804dSStefan Eßer /**
20844d4804dSStefan Eßer  * Write str to the file.
20944d4804dSStefan Eßer  * @param f     The file to flush.
21044d4804dSStefan Eßer  * @param type  The flush type.
21144d4804dSStefan Eßer  * @param str   The string to write to the file.
21244d4804dSStefan Eßer  */
21378bc019dSStefan Eßer void
21478bc019dSStefan Eßer bc_file_puts(BcFile* restrict f, BcFlushType type, const char* str);
2157e5c51e5SStefan Eßer 
21678bc019dSStefan Eßer #if BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB
21744d4804dSStefan Eßer 
21844d4804dSStefan Eßer // Some constant flush types for ease of use.
2197e5c51e5SStefan Eßer extern const BcFlushType bc_flush_none;
2207e5c51e5SStefan Eßer extern const BcFlushType bc_flush_err;
2217e5c51e5SStefan Eßer extern const BcFlushType bc_flush_save;
22244d4804dSStefan Eßer 
22378bc019dSStefan Eßer #endif // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB
224252884aeSStefan Eßer 
225252884aeSStefan Eßer #endif // BC_FILE_H
226