1*5a6e8488SAndroid Build Coastguard Worker /* 2*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 3*5a6e8488SAndroid Build Coastguard Worker * 4*5a6e8488SAndroid Build Coastguard Worker * SPDX-License-Identifier: BSD-2-Clause 5*5a6e8488SAndroid Build Coastguard Worker * 6*5a6e8488SAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7*5a6e8488SAndroid Build Coastguard Worker * 8*5a6e8488SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 9*5a6e8488SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 10*5a6e8488SAndroid Build Coastguard Worker * 11*5a6e8488SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright notice, this 12*5a6e8488SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 13*5a6e8488SAndroid Build Coastguard Worker * 14*5a6e8488SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright notice, 15*5a6e8488SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 16*5a6e8488SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 17*5a6e8488SAndroid Build Coastguard Worker * 18*5a6e8488SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5a6e8488SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5a6e8488SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5a6e8488SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5a6e8488SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5a6e8488SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5a6e8488SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5a6e8488SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5a6e8488SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5a6e8488SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5a6e8488SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE. 29*5a6e8488SAndroid Build Coastguard Worker * 30*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 31*5a6e8488SAndroid Build Coastguard Worker * 32*5a6e8488SAndroid Build Coastguard Worker * Definitions for implementing buffered I/O on my own terms. 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker */ 35*5a6e8488SAndroid Build Coastguard Worker 36*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_FILE_H 37*5a6e8488SAndroid Build Coastguard Worker #define BC_FILE_H 38*5a6e8488SAndroid Build Coastguard Worker 39*5a6e8488SAndroid Build Coastguard Worker #include <stdarg.h> 40*5a6e8488SAndroid Build Coastguard Worker 41*5a6e8488SAndroid Build Coastguard Worker #include <history.h> 42*5a6e8488SAndroid Build Coastguard Worker #include <vector.h> 43*5a6e8488SAndroid Build Coastguard Worker 44*5a6e8488SAndroid Build Coastguard Worker #define BC_FILE_ULL_LENGTH (21) 45*5a6e8488SAndroid Build Coastguard Worker 46*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_LINE_LIB 47*5a6e8488SAndroid Build Coastguard Worker 48*5a6e8488SAndroid Build Coastguard Worker #include <stdio.h> 49*5a6e8488SAndroid Build Coastguard Worker 50*5a6e8488SAndroid Build Coastguard Worker /// The file struct. 51*5a6e8488SAndroid Build Coastguard Worker typedef struct BcFile 52*5a6e8488SAndroid Build Coastguard Worker { 53*5a6e8488SAndroid Build Coastguard Worker // The file. This is here simply to make the line lib code as compatible 54*5a6e8488SAndroid Build Coastguard Worker // with the existing code as possible. 55*5a6e8488SAndroid Build Coastguard Worker FILE* f; 56*5a6e8488SAndroid Build Coastguard Worker 57*5a6e8488SAndroid Build Coastguard Worker // True if errors should be fatal, false otherwise. 58*5a6e8488SAndroid Build Coastguard Worker bool errors_fatal; 59*5a6e8488SAndroid Build Coastguard Worker 60*5a6e8488SAndroid Build Coastguard Worker } BcFile; 61*5a6e8488SAndroid Build Coastguard Worker 62*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_LINE_LIB 63*5a6e8488SAndroid Build Coastguard Worker 64*5a6e8488SAndroid Build Coastguard Worker /// The file struct. 65*5a6e8488SAndroid Build Coastguard Worker typedef struct BcFile 66*5a6e8488SAndroid Build Coastguard Worker { 67*5a6e8488SAndroid Build Coastguard Worker // The actual file descriptor. 68*5a6e8488SAndroid Build Coastguard Worker int fd; 69*5a6e8488SAndroid Build Coastguard Worker 70*5a6e8488SAndroid Build Coastguard Worker // True if errors should be fatal, false otherwise. 71*5a6e8488SAndroid Build Coastguard Worker bool errors_fatal; 72*5a6e8488SAndroid Build Coastguard Worker 73*5a6e8488SAndroid Build Coastguard Worker // The buffer for the file. 74*5a6e8488SAndroid Build Coastguard Worker char* buf; 75*5a6e8488SAndroid Build Coastguard Worker 76*5a6e8488SAndroid Build Coastguard Worker // The length (number of actual chars) in the buffer. 77*5a6e8488SAndroid Build Coastguard Worker size_t len; 78*5a6e8488SAndroid Build Coastguard Worker 79*5a6e8488SAndroid Build Coastguard Worker // The capacity (max number of chars) of the buffer. 80*5a6e8488SAndroid Build Coastguard Worker size_t cap; 81*5a6e8488SAndroid Build Coastguard Worker 82*5a6e8488SAndroid Build Coastguard Worker } BcFile; 83*5a6e8488SAndroid Build Coastguard Worker 84*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LINE_LIB 85*5a6e8488SAndroid Build Coastguard Worker 86*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB 87*5a6e8488SAndroid Build Coastguard Worker 88*5a6e8488SAndroid Build Coastguard Worker /// Types of flushing. These are important because of history and printing 89*5a6e8488SAndroid Build Coastguard Worker /// strings without newlines, something that users could use as their own 90*5a6e8488SAndroid Build Coastguard Worker /// prompts. 91*5a6e8488SAndroid Build Coastguard Worker typedef enum BcFlushType 92*5a6e8488SAndroid Build Coastguard Worker { 93*5a6e8488SAndroid Build Coastguard Worker /// Do not clear the stored partial line, but don't add to it. 94*5a6e8488SAndroid Build Coastguard Worker BC_FLUSH_NO_EXTRAS_NO_CLEAR, 95*5a6e8488SAndroid Build Coastguard Worker 96*5a6e8488SAndroid Build Coastguard Worker /// Do not clear the stored partial line and add to it. 97*5a6e8488SAndroid Build Coastguard Worker BC_FLUSH_SAVE_EXTRAS_NO_CLEAR, 98*5a6e8488SAndroid Build Coastguard Worker 99*5a6e8488SAndroid Build Coastguard Worker /// Clear the stored partial line and do not save the new stuff either. 100*5a6e8488SAndroid Build Coastguard Worker BC_FLUSH_NO_EXTRAS_CLEAR, 101*5a6e8488SAndroid Build Coastguard Worker 102*5a6e8488SAndroid Build Coastguard Worker /// Clear the stored partial line, but save the new stuff. 103*5a6e8488SAndroid Build Coastguard Worker BC_FLUSH_SAVE_EXTRAS_CLEAR, 104*5a6e8488SAndroid Build Coastguard Worker 105*5a6e8488SAndroid Build Coastguard Worker } BcFlushType; 106*5a6e8488SAndroid Build Coastguard Worker 107*5a6e8488SAndroid Build Coastguard Worker // These are here to satisfy a clang warning about recursive macros. 108*5a6e8488SAndroid Build Coastguard Worker 109*5a6e8488SAndroid Build Coastguard Worker #define bc_file_putchar(f, t, c) bc_file_putchar_impl(f, t, c) 110*5a6e8488SAndroid Build Coastguard Worker #define bc_file_flushErr(f, t) bc_file_flushErr_impl(f, t) 111*5a6e8488SAndroid Build Coastguard Worker #define bc_file_flush(f, t) bc_file_flush_impl(f, t) 112*5a6e8488SAndroid Build Coastguard Worker #define bc_file_write(f, t, b, n) bc_file_write_impl(f, t, b, n) 113*5a6e8488SAndroid Build Coastguard Worker #define bc_file_puts(f, t, s) bc_file_puts_impl(f, t, s) 114*5a6e8488SAndroid Build Coastguard Worker 115*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB 116*5a6e8488SAndroid Build Coastguard Worker 117*5a6e8488SAndroid Build Coastguard Worker // These make sure that the BcFlushType parameter disappears if history is not 118*5a6e8488SAndroid Build Coastguard Worker // used, editline is used, or readline is used. 119*5a6e8488SAndroid Build Coastguard Worker 120*5a6e8488SAndroid Build Coastguard Worker #define bc_file_putchar(f, t, c) bc_file_putchar_impl(f, c) 121*5a6e8488SAndroid Build Coastguard Worker #define bc_file_flushErr(f, t) bc_file_flushErr_impl(f) 122*5a6e8488SAndroid Build Coastguard Worker #define bc_file_flush(f, t) bc_file_flush_impl(f) 123*5a6e8488SAndroid Build Coastguard Worker #define bc_file_write(f, t, b, n) bc_file_write_impl(f, b, n) 124*5a6e8488SAndroid Build Coastguard Worker #define bc_file_puts(f, t, s) bc_file_puts_impl(f, s) 125*5a6e8488SAndroid Build Coastguard Worker 126*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB 127*5a6e8488SAndroid Build Coastguard Worker 128*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_LINE_LIB 129*5a6e8488SAndroid Build Coastguard Worker 130*5a6e8488SAndroid Build Coastguard Worker /** 131*5a6e8488SAndroid Build Coastguard Worker * Initialize a file. 132*5a6e8488SAndroid Build Coastguard Worker * @param f The file to initialize. 133*5a6e8488SAndroid Build Coastguard Worker * @param file The stdio file. 134*5a6e8488SAndroid Build Coastguard Worker * @param errors_fatal True if errors should be fatal, false otherwise. 135*5a6e8488SAndroid Build Coastguard Worker */ 136*5a6e8488SAndroid Build Coastguard Worker void 137*5a6e8488SAndroid Build Coastguard Worker bc_file_init(BcFile* f, FILE* file, bool errors_fatal); 138*5a6e8488SAndroid Build Coastguard Worker 139*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_LINE_LIB 140*5a6e8488SAndroid Build Coastguard Worker 141*5a6e8488SAndroid Build Coastguard Worker /** 142*5a6e8488SAndroid Build Coastguard Worker * Initialize a file. 143*5a6e8488SAndroid Build Coastguard Worker * @param f The file to initialize. 144*5a6e8488SAndroid Build Coastguard Worker * @param fd The file descriptor. 145*5a6e8488SAndroid Build Coastguard Worker * @param buf The buffer for the file. 146*5a6e8488SAndroid Build Coastguard Worker * @param cap The capacity of the buffer. 147*5a6e8488SAndroid Build Coastguard Worker * @param errors_fatal True if errors should be fatal, false otherwise. 148*5a6e8488SAndroid Build Coastguard Worker */ 149*5a6e8488SAndroid Build Coastguard Worker void 150*5a6e8488SAndroid Build Coastguard Worker bc_file_init(BcFile* f, int fd, char* buf, size_t cap, bool errors_fatal); 151*5a6e8488SAndroid Build Coastguard Worker 152*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_LINE_LIB 153*5a6e8488SAndroid Build Coastguard Worker 154*5a6e8488SAndroid Build Coastguard Worker /** 155*5a6e8488SAndroid Build Coastguard Worker * Frees a file, including flushing it. 156*5a6e8488SAndroid Build Coastguard Worker * @param f The file to free. 157*5a6e8488SAndroid Build Coastguard Worker */ 158*5a6e8488SAndroid Build Coastguard Worker void 159*5a6e8488SAndroid Build Coastguard Worker bc_file_free(BcFile* f); 160*5a6e8488SAndroid Build Coastguard Worker 161*5a6e8488SAndroid Build Coastguard Worker /** 162*5a6e8488SAndroid Build Coastguard Worker * Print a char into the file. 163*5a6e8488SAndroid Build Coastguard Worker * @param f The file to print to. 164*5a6e8488SAndroid Build Coastguard Worker * @param type The flush type. 165*5a6e8488SAndroid Build Coastguard Worker * @param c The character to write. 166*5a6e8488SAndroid Build Coastguard Worker */ 167*5a6e8488SAndroid Build Coastguard Worker void 168*5a6e8488SAndroid Build Coastguard Worker bc_file_putchar(BcFile* restrict f, BcFlushType type, uchar c); 169*5a6e8488SAndroid Build Coastguard Worker 170*5a6e8488SAndroid Build Coastguard Worker /** 171*5a6e8488SAndroid Build Coastguard Worker * Flush and return an error if it failed. This is meant to be used when needing 172*5a6e8488SAndroid Build Coastguard Worker * to flush in error situations when an error is already in flight. It would be 173*5a6e8488SAndroid Build Coastguard Worker * a very bad deal to throw another error. 174*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 175*5a6e8488SAndroid Build Coastguard Worker * @param type The flush type. 176*5a6e8488SAndroid Build Coastguard Worker * @return A status indicating if an error occurred. 177*5a6e8488SAndroid Build Coastguard Worker */ 178*5a6e8488SAndroid Build Coastguard Worker BcStatus 179*5a6e8488SAndroid Build Coastguard Worker bc_file_flushErr(BcFile* restrict f, BcFlushType type); 180*5a6e8488SAndroid Build Coastguard Worker 181*5a6e8488SAndroid Build Coastguard Worker /** 182*5a6e8488SAndroid Build Coastguard Worker * Flush and throw an error on failure. 183*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 184*5a6e8488SAndroid Build Coastguard Worker * @param type The flush type. 185*5a6e8488SAndroid Build Coastguard Worker */ 186*5a6e8488SAndroid Build Coastguard Worker void 187*5a6e8488SAndroid Build Coastguard Worker bc_file_flush(BcFile* restrict f, BcFlushType type); 188*5a6e8488SAndroid Build Coastguard Worker 189*5a6e8488SAndroid Build Coastguard Worker /** 190*5a6e8488SAndroid Build Coastguard Worker * Write the contents of buf to the file. 191*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 192*5a6e8488SAndroid Build Coastguard Worker * @param type The flush type. 193*5a6e8488SAndroid Build Coastguard Worker * @param buf The buffer whose contents will be written to the file. 194*5a6e8488SAndroid Build Coastguard Worker * @param n The length of buf. 195*5a6e8488SAndroid Build Coastguard Worker */ 196*5a6e8488SAndroid Build Coastguard Worker void 197*5a6e8488SAndroid Build Coastguard Worker bc_file_write(BcFile* restrict f, BcFlushType type, const char* buf, size_t n); 198*5a6e8488SAndroid Build Coastguard Worker 199*5a6e8488SAndroid Build Coastguard Worker /** 200*5a6e8488SAndroid Build Coastguard Worker * Write to the file like fprintf would. This is very rudimentary. 201*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 202*5a6e8488SAndroid Build Coastguard Worker * @param fmt The format string. 203*5a6e8488SAndroid Build Coastguard Worker */ 204*5a6e8488SAndroid Build Coastguard Worker void 205*5a6e8488SAndroid Build Coastguard Worker bc_file_printf(BcFile* restrict f, const char* fmt, ...); 206*5a6e8488SAndroid Build Coastguard Worker 207*5a6e8488SAndroid Build Coastguard Worker /** 208*5a6e8488SAndroid Build Coastguard Worker * Write to the file like vfprintf would. This is very rudimentary. 209*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 210*5a6e8488SAndroid Build Coastguard Worker * @param fmt The format string. 211*5a6e8488SAndroid Build Coastguard Worker */ 212*5a6e8488SAndroid Build Coastguard Worker void 213*5a6e8488SAndroid Build Coastguard Worker bc_file_vprintf(BcFile* restrict f, const char* fmt, va_list args); 214*5a6e8488SAndroid Build Coastguard Worker 215*5a6e8488SAndroid Build Coastguard Worker /** 216*5a6e8488SAndroid Build Coastguard Worker * Write str to the file. 217*5a6e8488SAndroid Build Coastguard Worker * @param f The file to flush. 218*5a6e8488SAndroid Build Coastguard Worker * @param type The flush type. 219*5a6e8488SAndroid Build Coastguard Worker * @param str The string to write to the file. 220*5a6e8488SAndroid Build Coastguard Worker */ 221*5a6e8488SAndroid Build Coastguard Worker void 222*5a6e8488SAndroid Build Coastguard Worker bc_file_puts(BcFile* restrict f, BcFlushType type, const char* str); 223*5a6e8488SAndroid Build Coastguard Worker 224*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB 225*5a6e8488SAndroid Build Coastguard Worker 226*5a6e8488SAndroid Build Coastguard Worker // Some constant flush types for ease of use. 227*5a6e8488SAndroid Build Coastguard Worker extern const BcFlushType bc_flush_none; 228*5a6e8488SAndroid Build Coastguard Worker extern const BcFlushType bc_flush_err; 229*5a6e8488SAndroid Build Coastguard Worker extern const BcFlushType bc_flush_save; 230*5a6e8488SAndroid Build Coastguard Worker 231*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_HISTORY && !BC_ENABLE_LINE_LIB 232*5a6e8488SAndroid Build Coastguard Worker 233*5a6e8488SAndroid Build Coastguard Worker #endif // BC_FILE_H 234