// vim: ts=4 sw=4 expandtab ft=c // Copyright (C) 2000, 2002 The University of Melbourne. // Copyright (C) 2016, 2018 The Mercury team. // This file is distributed under the terms specified in COPYING.LIB. // This module contains the implementation of Mercury streams using // C `FILE *' streams. #include "mercury_file.h" #include "mercury_std.h" // for MR_assert #ifdef MR_NATIVE_GC static int next_id = 0; #endif #ifndef MR_NEW_MERCURYFILE_STRUCT void MR_mercuryfile_init(FILE *file, int line_number, MercuryFile *mf) { MR_file(*mf) = file; MR_line_number(*mf) = line_number; #ifdef MR_NATIVE_GC mf->id = ++next_id; #endif } #else // MR_NEW_MERCURYFILE_STRUCT void MR_mercuryfile_init(FILE *file, int line_number, MercuryFile *mf) { mf->stream_type = MR_FILE_STREAM; mf->stream_info.file = file; mf->line_number = line_number; mf->close = MR_close; mf->read = MR_read; mf->write = MR_write; mf->flush = MR_flush; mf->ungetc = MR_ungetch; mf->getc = MR_getch; mf->vprintf = MR_vfprintf; mf->putc = MR_putch; mf->ferror = MR_ferror; #ifdef MR_NATIVE_GC mf->id = ++next_id; #endif } int MR_getch(MR_StreamInfo *info) { MR_assert(info != NULL); return getc(info->file); } int MR_ungetch(MR_StreamInfo *info, int ch) { MR_assert(info != NULL); return ungetc(ch, info->file); } int MR_putch(MR_StreamInfo *info, int ch) { MR_assert(info != NULL); return putc(ch, info->file); } int MR_ferror(MR_StreamInfo *info) { MR_assert(info != NULL); return ferror(info->file); } int MR_close(MR_StreamInfo *info) { MR_assert(info != NULL); return fclose(info->file); } int MR_flush(MR_StreamInfo *info) { MR_assert(info != NULL); return fflush(info->file); } int MR_vfprintf(MR_StreamInfo *info, const char *format, va_list ap) { MR_assert(info != NULL); MR_assert(format != NULL); return vfprintf(info->file, format, ap); } int MR_read(MR_StreamInfo *info, void *buffer, size_t size) { int rc; MR_assert(info != NULL); rc = fread(buffer, sizeof(unsigned char), size, info->file); // Handle error/eof special cases. if ((rc < size) && feof(info->file)) { // Nothing to do. ; } else if (ferror(info->file)) { rc = -1; } return rc; } int MR_write(MR_StreamInfo *info, const void *buffer, size_t size) { int rc; MR_assert(info != NULL); rc = fwrite(buffer, sizeof(unsigned char), size, info->file); return (rc < size ? -1 : rc); } #endif // MR_NEW_MERCURYFILE_STRUCT