/* Implement Input/Output runtime actions for CHILL. Copyright (C) 1992,1993 Free Software Foundation, Inc. Author: Wilfried Moser, et al This file is part of GNU CC. GNU CC 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, or (at your option) any later version. GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "fileio.h" static void doWrite( Access_Mode* the_access, void* buf, size_t nbyte ) { size_t nwrit; nwrit = write( the_access->association->handle, buf, nbyte ); if( nwrit < nbyte ) { the_access->association->syserrno = errno; RWEXCEPTION( WRITEFAIL, OS_IO_ERROR ); } } void __writerecord( Access_Mode* the_access, signed long the_index, char* the_val_addr, unsigned long the_val_len, char* file, int line ) { Association_Mode* the_assoc; unsigned long info; char* actaddr; unsigned short actlen; off_t filepos; if( !the_access ) CHILLEXCEPTION( file, line, EMPTY, NULL_ACCESS ); if( !(the_assoc = the_access->association) ) CHILLEXCEPTION( file, line, NOTCONNECTED, IS_NOT_CONNECTED ); /* Usage must no be ReadOnly */ if( the_assoc->usage == ReadOnly ) CHILLEXCEPTION( file, line, WRITEFAIL, BAD_USAGE ); /* * Positioning */ if( TEST_FLAG( the_access, IO_INDEXED ) ) { /* index expression must be within bounds of index mode */ if( the_index < the_access->lowindex || the_access->highindex < the_index ) CHILLEXCEPTION( file, line, RANGEFAIL, BAD_INDEX ); filepos = the_access->base + (the_index - the_access->lowindex) * the_access->reclength; if( lseek( the_assoc->handle, filepos, SEEK_SET ) == -1L ) CHILLEXCEPTION( file, line, WRITEFAIL, LSEEK_FAILS ); } if( (info = setjmp( __rw_exception )) ) CHILLEXCEPTION( file, line, info>>16, info & 0xffff ); if( TEST_FLAG( the_access, IO_TEXTIO ) ) { if( TEST_FLAG( the_access, IO_INDEXED ) ) { int nspace = the_access->reclength - the_val_len; memset( the_val_addr + 2 + the_val_len, ' ', nspace ); actlen = the_access->reclength - 2; MOV2(the_val_addr,&actlen); doWrite( the_access, the_val_addr, the_access->reclength ); } else { if( the_assoc->ctl_pre ) write( the_assoc->handle, &the_assoc->ctl_pre, 1 ); MOV2(&actlen,the_val_addr); write( the_assoc->handle, the_val_addr + 2, actlen ); if( the_assoc->ctl_post ) write( the_assoc->handle, &the_assoc->ctl_post, 1 ); the_assoc->ctl_pre = '\0'; the_assoc->ctl_post = '\n'; } } else { switch( the_access->rectype ) { case Fixed: if( TEST_FLAG( the_assoc, IO_VARIABLE ) ) { actlen = the_access->reclength; doWrite( the_access, &actlen, sizeof(actlen) ); } doWrite( the_access, the_val_addr, the_val_len ); break; case VaryingChars: MOV2(&actlen,the_val_addr); if( actlen > the_access->reclength - 2 ) CHILLEXCEPTION( file, line, RANGEFAIL, RECORD_TOO_LONG ); actlen = TEST_FLAG( the_access, IO_INDEXED ) ? the_access->reclength : actlen + 2; doWrite( the_access, the_val_addr, actlen ); break; } } }