/*############################################################################## FUNNNELWEB COPYRIGHT ==================== FunnelWeb is a literate-programming macro preprocessor. The FunnelWeb web is at http://www.ross.net/funnelweb/ Copyright (c) Ross N. Williams 1992. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of Version 2 of the GNU General Public License as published by the Free Software Foundation (http://www.gnu.org/). This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 of the GNU General Public License for more details. You should have received a copy of Version 2 of the GNU General Public License along with this program. If not, you can obtain a copy as follows: ftp://prep.ai.mit.edu/pub/gnu/COPYING-2.0 or write to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Section 2a of the license requires that all changes to this file be recorded prominently in this file. Please record all changes here. Programmers: RNW Ross N. Williams (ross@ross.net) Changes: 07-May-1992 RNW Program prepared for release under GNU GPL V2. 08-May-1999 RNW Added function wr_dup. ##############################################################################*/ /******************************************************************************/ /* WRITFILE.H */ /******************************************************************************/ /* */ /* Introduction */ /* ------------ */ /* This package performs all of FunnelWeb's file output. */ /* FunnelWeb performs lots of output to lots of different files: */ /* */ /* - Standard output (to write to the screen). */ /* - The journal file. */ /* - The listing file. */ /* - The tangle output files. */ /* - The weave output file. */ /* */ /* Error Detection */ /* --------------- */ /* As we are serious about detecting errors, every call to every IO function */ /* must have its status checked. Unfortunately this makes everything very */ /* messy. Having to check result statuses and react to them can be very */ /* awkward in deeply nested pieces of code, particularly as C does not have */ /* exceptions. As a result, the policy adopted in FunnelWeb is to RECORD when */ /* an error occurs on an output stream and silently shut down that stream. */ /* Then later, at a convenient time, the error status of the stream can be */ /* checked, and an error message issued. */ /* */ /* The C libraries make an effort to be helpful here by providing the ferror */ /* function. However, it is not useful here for two reasons: */ /* */ /* 1. Some calls (e.g. fwrite) are not listed as setting the error status. */ /* 2. It is not guaranteed that IO calls to a stream with error status */ /* will not cause a crash. */ /* 3. Even if ferror were used, it may not be supported by older compilers.*/ /* */ /* This package was created to take care of the vexing problems of IO errors */ /* in output streams. It is a layer above the ANSI file library that provides */ /* the elementary calls for writing. It differs in that if an error occurs, */ /* the package records that fact and simply ignores all further operations */ /* on the file. At any time, it is possible to find out whether a file is in */ /* normal mode or error mode. All this means that a piece of code can use */ /* this package to create and write to a file without worrying about errors. */ /* Then later, when the dust settles, the package can check the status of */ /* the file, and take appropriate action if an error has been detected. */ /* */ /* Text vs Binary */ /* -------------- */ /* This package translates all '\n' (contained in the data it has been given */ /* to write) into the appropriate environment specific representation. */ /* */ /* Facts About WF Objects */ /* ---------------------- */ /* - A WF object is either in NORMAL or ERROR mode. */ /* - A WF object in NORMAL mode is also either in OPEN or CLOSED mode. */ /* - The term "raise an error" means bomb the program with a message. */ /* - The comments attached to the functions given below are meant to be read */ /* sequentially with each action or check being performed before the next. */ /* - This package can not guarantee to detect uninitialized WF objects. The */ /* reason is that policing is performed using magic number mechanism and it */ /* is possible that a piece of random memory may contain just the right */ /* numbers to fool the package. */ /* */ /******************************************************************************/ /* Ensure that the body of this header file is included at most once. */ #ifndef DONE_WRITFILE #define DONE_WRITFILE /******************************************************************************/ #include "style.h" /******************************************************************************/ /* We really don't want to show all the guts of this record here, but as */ /* users of the package have to be able to declare objects of this type and */ /* make them the right size, it seems as if we have no choice. */ typedef struct { ulong wf_mhead; /* Helps detect uninitialized and corrupted records. */ bool wf_iserr; /* TRUE=>ERROR, FALSE=>NORMAL. */ bool wf_isope; /* TRUE=>OPEN, FALSE=>CLOSED. */ bool wf_istxt; /* TRUE=>TEXT, FALSE=>BINARY. */ FILE *wf_pfile; /* Pointer to the file object. */ ulong wf_mtail; /* Helps detect uninitialized and corrupted records. */ } wf_t; typedef wf_t *p_wf_t; /******************************************************************************/ EXPORT void wf_ini P_((p_wf_t,bool)); /* Initializes a WF to a well defined state in accordance with the boolean. */ /* FALSE => State=(ERROR). */ /* TRUE => State=(NORMAL,CLOSED). */ /* wf_ini must be applied to a WF before any other operation. */ /* It can be re-applied repeatedly. */ EXPORT void wf_att P_((p_wf_t,FILE *)); /* If WF is uninitialized, raises an error (probably). */ /* If WF is in ERROR mode, returns with no effect. */ /* If WF is OPEN, raises an error. */ /* Attaches an already opened output file to the specified FW object. */ /* Changes the WF to the OPEN state. */ /* The memory that the second parameter points to must be stable. */ EXPORT void wf_ope P_((p_wf_t,char *)); /* If WF is uninitialized, raises an error (probably). */ /* If WF is in ERROR mode, returns with no effect. */ /* If WF is OPEN, raises an error. */ /* Creates an output file of the specified name and prepares it for writing. */ /* Changes the WF to the OPEN state. */ /* Sets the WF to the ERROR state if the file cannot be opened for writing. */ EXPORT void wf_chr P_((p_wf_t,intchar)); /* If WF is uninitialized, raises an error (probably). */ /* If WF is in ERROR mode, returns with no effect. */ /* If WF is CLOSED, raises an error. */ /* Writes the specified character to the output file associated with WF. */ /* Sets WF to the ERROR state if an error occurs during the write. */ EXPORT void wf_wr P_((p_wf_t,char *)); /* Same as wf_chr except that it writes an entire string. */ EXPORT void wf_wl P_((p_wf_t,char *)); /* Same as wf_wr except that appends a '\n'. */ EXPORT void wf_blk P_((p_wf_t,char *,size_t)); /* Same as wf_wr but writes a block of bytes whose address is given by the */ /* second parameter and whose length (in bytes) is given by the third */ /* parameter. */ EXPORT void wf_dup P_((p_wf_t,intchar,ulong)); /* Same as wf_wr but writes specified number of copies of specified char. */ /* The character must not be a NUL. */ EXPORT void wf_clo P_((p_wf_t)); /* If WF is uninitialized, raises an error (probably). */ /* If WF is in ERROR mode, returns with no effect. */ /* If WF is CLOSED, raises an error. */ /* Flushes and closes the output file attached to WF. */ /* Sets WF to the CLOSED state. */ /* Sets WF to the ERROR state if an error occurs during the close. */ EXPORT bool wf_err P_((p_wf_t)); /* If WF is uninitialized, raises an error (probably). */ /* Returns TRUE iff WF is in the ERROR state, otherwise FALSE. */ /* This function can be called at any time so long as the WF is initialized. */ /******************************************************************************/ /* For #ifndef preventing multiple inclusion of the body of this header file. */ #endif /******************************************************************************/ /* End of WRITFILE.H */ /******************************************************************************/