Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Thu, 21 Jul 2016 11:08:42 UTC Commit: 18b7527fcc237053716c5b8d54a15c1d36dca0ef https://github.com/geany/geany/commit/18b7527fcc237053716c5b8d54a15c1d36dca0...
Log Message: ----------- Use the single-file implementation of MIO from universal-ctags
The version of MIO corresponds to commit 509a47dbc in universal-ctags which contains just minimal changes mostly related to changing MIO from a library into a single ctags source file:
- replaced the glib types with ordinary C types - removed the "virtual" calls and replaced them with simple if/else - made the implementation in a single file - reformatted the library to more or less match universal-ctags style - removed the MIO_FORCE_ANSI ifdef as it included some glib file and we don't really need it - added mio_flush() - of course makes sense just for the file backend (calls fflush()) - made mio_free() return error code from fclose() - changed mio_new_fp() to return NULL when the passed FILE is NULL (simplifies logic at one place in ctags and makes sense IMO)
Modified Paths: -------------- configure.ac ctags/Makefile.am ctags/main/Makefile.am ctags/main/c.c ctags/main/entry.h ctags/main/fortran.c ctags/main/js.c ctags/main/lregex.c ctags/main/mio.c ctags/main/mio.h ctags/main/parse.c ctags/main/read.h ctags/mio/COPYING ctags/mio/Makefile.am ctags/mio/README ctags/mio/makefile.win32 ctags/mio/mio-file.c ctags/mio/mio-memory.c ctags/mio/mio.c ctags/mio/mio.h
Modified: configure.ac 1 lines changed, 0 insertions(+), 1 deletions(-) =================================================================== @@ -149,7 +149,6 @@ AC_CONFIG_FILES([ icons/tango/scalable/Makefile ctags/Makefile ctags/main/Makefile - ctags/mio/Makefile scintilla/Makefile scintilla/include/Makefile src/Makefile
Modified: ctags/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1,3 +1,3 @@ ## Process this file with automake to produce Makefile.in
-SUBDIRS = mio main +SUBDIRS = main
Modified: ctags/main/Makefile.am 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -11,8 +11,6 @@ EXTRA_DIST = \
noinst_LTLIBRARIES = libctags.la
-libctags_la_LIBADD = ../mio/libmio.la - parsers = \ abaqus.c \ abc.c \ @@ -71,6 +69,8 @@ libctags_la_SOURCES = \ keyword.c \ keyword.h \ main.h \ + mio.c \ + mio.h \ nestlevel.c \ nestlevel.h \ options.c \
Modified: ctags/main/c.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -16,8 +16,8 @@
#include <string.h> #include <setjmp.h> -#include <mio/mio.h>
+#include "mio.h" #include "entry.h" #include "get.h" #include "keyword.h"
Modified: ctags/main/entry.h 3 lines changed, 1 insertions(+), 2 deletions(-) =================================================================== @@ -15,8 +15,7 @@ */ #include "general.h" /* must always come first */
-#include <mio/mio.h> - +#include "mio.h" #include "vstring.h"
/*
Modified: ctags/main/fortran.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -17,8 +17,8 @@ #include <limits.h> #include <ctype.h> /* to define tolower () */ #include <setjmp.h> -#include <mio/mio.h>
+#include "mio.h" #include "entry.h" #include "keyword.h" #include "main.h"
Modified: ctags/main/js.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -19,11 +19,11 @@ #include "general.h" /* must always come first */ #include <ctype.h> /* to define isalpha () */ #include <string.h> -#include <mio/mio.h> #ifdef DEBUG #include <stdio.h> #endif
+#include "mio.h" #include "keyword.h" #include "parse.h" #include "read.h"
Modified: ctags/main/lregex.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -18,7 +18,6 @@
#include <string.h> #include <glib.h> -#include <mio/mio.h>
#ifdef HAVE_REGCOMP # include <ctype.h> @@ -28,6 +27,7 @@ # endif #endif
+#include "mio.h" #include "main.h" #include "entry.h" #include "parse.h"
Modified: ctags/main/mio.c 1063 lines changed, 1063 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,1063 @@ +/* + * MIO, an I/O abstraction layer replicating C file I/O API. + * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "mio.h" + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <limits.h> + +/* minimal reallocation chunk size */ +#define MIO_CHUNK_SIZE 4096 + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +/** + * SECTION:mio + * @short_description: The MIO object + * @include: mio/mio.h + * + * The #MIO object replicates the C file I/O API with support of both standard + * file based operations and in-memory operations. Its goal is to ease the port + * of an application that uses C file I/O API to perform in-memory operations. + * + * A #MIO object is created using mio_new_file() or mio_new_memory(), depending + * on whether you want file or in-memory operations, and destroyed using + * mio_free(). There is also some other convenient API to create file-based + * #MIO objects for more complex cases, such as mio_new_file_full() and + * mio_new_fp(). + * + * Once the #MIO object is created, you can perform standard I/O operations on + * it transparently without the need to care about the effective underlying + * operations. + * + * The I/O API is almost exactly a replication of the standard C file I/O API + * with the significant difference that the first parameter is always the #MIO + * object to work on. + */ + + +/** + * mio_new_file_full: + * @filename: Filename to open, passed as-is to @open_func as the first argument + * @mode: Mode in which open the file, passed as-is to @open_func as the second + * argument + * @open_func: A function with the fopen() semantic to use to open the file + * @close_func: A function with the fclose() semantic to close the file when + * the #MIO object is destroyed, or %NULL not to close the #FILE + * object + * + * Creates a new #MIO object working on a file, from a filename and an opening + * function. See also mio_new_file(). + * + * This function is generally overkill and mio_new_file() should often be used + * instead, but it allows to specify a custom function to open a file, as well + * as a close function. The former is useful e.g. if you need to wrap fopen() + * for some reason (like filename encoding conversion for example), and the + * latter allows you both to match your custom open function and to choose + * whether the underlying #FILE object should or not be closed when mio_free() + * is called on the returned object. + * + * Free-function: mio_free() + * + * Returns: A new #MIO on success, or %NULL on failure. + */ +MIO *mio_new_file_full (const char *filename, + const char *mode, + MIOFOpenFunc open_func, + MIOFCloseFunc close_func) +{ + MIO *mio; + + /* we need to create the MIO object first, because we may not be able to close + * the opened file if the user passed NULL as the close function, which means + * that everything must succeed if we've opened the file successfully */ + mio = malloc (sizeof *mio); + if (mio) + { + FILE *fp = open_func (filename, mode); + + if (! fp) + { + free (mio); + mio = NULL; + } + else + { + mio->type = MIO_TYPE_FILE; + mio->impl.file.fp = fp; + mio->impl.file.close_func = close_func; + } + } + + return mio; +} + +/** + * mio_new_file: + * @filename: Filename to open, same as the fopen()'s first argument + * @mode: Mode in which open the file, fopen()'s second argument + * + * Creates a new #MIO object working on a file from a filename; wrapping + * fopen(). + * This function simply calls mio_new_file_full() with the libc's fopen() and + * fclose() functions. + * + * Free-function: mio_free() + * + * Returns: A new #MIO on success, or %NULL on failure. + */ +MIO *mio_new_file (const char *filename, const char *mode) +{ + return mio_new_file_full (filename, mode, fopen, fclose); +} + +/** + * mio_new_fp: + * @fp: An opened #FILE object + * @close_func: (allow-none): Function used to close @fp when the #MIO object + * gets destroyed, or %NULL not to close the #FILE object + * + * Creates a new #MIO object working on a file, from an already opened #FILE + * object. + * + * <example> + * <title>Typical use of this function</title> + * <programlisting> + * MIO *mio = mio_new_fp (fp, fclose); + * </programlisting> + * </example> + * + * Free-function: mio_free() + * + * Returns: A new #MIO on success or %NULL on failure. + */ +MIO *mio_new_fp (FILE *fp, MIOFCloseFunc close_func) +{ + MIO *mio; + + if (!fp) + return NULL; + + mio = malloc (sizeof *mio); + if (mio) + { + mio->type = MIO_TYPE_FILE; + mio->impl.file.fp = fp; + mio->impl.file.close_func = close_func; + } + + return mio; +} + +/** + * mio_new_memory: + * @data: Initial data (may be %NULL) + * @size: Length of @data in bytes + * @realloc_func: A function with the realloc() semantic used to grow the + * buffer, or %NULL to disable buffer growing + * @free_func: A function with the free() semantic to destroy the data together + * with the object, or %NULL not to destroy the data + * + * Creates a new #MIO object working on memory. + * + * To allow the buffer to grow, you must provide a @realloc_func, otherwise + * trying to write after the end of the current data will fail. + * + * If you want the buffer to be freed together with the #MIO object, you must + * give a @free_func; otherwise the data will still live after #MIO object + * termination. + * + * <example> + * <title>Basic creation of a non-growable, freeable #MIO object</title> + * <programlisting> + * MIO *mio = mio_new_memory (data, size, NULL, g_free); + * </programlisting> + * </example> + * + * <example> + * <title>Basic creation of an empty growable and freeable #MIO object</title> + * <programlisting> + * MIO *mio = mio_new_memory (NULL, 0, g_try_realloc, g_free); + * </programlisting> + * </example> + * + * Free-function: mio_free() + * + * Returns: A new #MIO on success, or %NULL on failure. + */ +MIO *mio_new_memory (unsigned char *data, + size_t size, + MIOReallocFunc realloc_func, + MIODestroyNotify free_func) +{ + MIO *mio; + + mio = malloc (sizeof *mio); + if (mio) + { + mio->type = MIO_TYPE_MEMORY; + mio->impl.mem.buf = data; + mio->impl.mem.ungetch = EOF; + mio->impl.mem.pos = 0; + mio->impl.mem.size = size; + mio->impl.mem.allocated_size = size; + mio->impl.mem.realloc_func = realloc_func; + mio->impl.mem.free_func = free_func; + mio->impl.mem.eof = FALSE; + mio->impl.mem.error = FALSE; + } + + return mio; +} + +/** + * mio_file_get_fp: + * @mio: A #MIO object + * + * Gets the underlying #FILE object associated with a #MIO file stream. + * + * <warning><para>The returned object may become invalid after a call to + * mio_free() if the stream was configured to close the file when + * destroyed.</para></warning> + * + * Returns: The underlying #FILE object of the given stream, or %NULL if the + * stream is not a file stream. + */ +FILE *mio_file_get_fp (MIO *mio) +{ + FILE *fp = NULL; + + if (mio->type == MIO_TYPE_FILE) + fp = mio->impl.file.fp; + + return fp; +} + +/** + * mio_memory_get_data: + * @mio: A #MIO object + * @size: (allow-none) (out): Return location for the length of the returned + * memory, or %NULL + * + * Gets the underlying memory buffer associated with a #MIO memory stream. + * + * <warning><para>The returned pointer and size may become invalid after a + * successful write on the stream or after a call to mio_free() if the stream + * was configured to free the memory when destroyed.</para></warning> + * + * Returns: The memory buffer of the given #MIO stream, or %NULL if the stream + * is not a memory stream. + */ +unsigned char *mio_memory_get_data (MIO *mio, size_t *size) +{ + unsigned char *ptr = NULL; + + if (mio->type == MIO_TYPE_MEMORY) + { + ptr = mio->impl.mem.buf; + if (size) + *size = mio->impl.mem.size; + } + + return ptr; +} + +/** + * mio_free: + * @mio: A #MIO object + * + * Destroys a #MIO object. + * + * Returns: Error code obtained from the registered MIOFCloseFunc or 0 on success. + */ +int mio_free (MIO *mio) +{ + int rv = 0; + + if (mio) + { + if (mio->type == MIO_TYPE_FILE) + { + if (mio->impl.file.close_func) + rv = mio->impl.file.close_func (mio->impl.file.fp); + mio->impl.file.close_func = NULL; + mio->impl.file.fp = NULL; + } + else + { + if (mio->impl.mem.free_func) + mio->impl.mem.free_func (mio->impl.mem.buf); + mio->impl.mem.buf = NULL; + mio->impl.mem.pos = 0; + mio->impl.mem.size = 0; + mio->impl.mem.allocated_size = 0; + mio->impl.mem.realloc_func = NULL; + mio->impl.mem.free_func = NULL; + mio->impl.mem.eof = FALSE; + mio->impl.mem.error = FALSE; + } + + free (mio); + } + + return rv; +} + +/** + * mio_read: + * @mio: A #MIO object + * @ptr: Pointer to the memory to fill with the read data + * @size: Size of each block to read + * @nmemb: Number o blocks to read + * + * Reads raw data from a #MIO stream. This function behave the same as fread(). + * + * Returns: The number of actually read blocks. If an error occurs or if the + * end of the stream is reached, the return value may be smaller than + * the requested block count, or even 0. This function doesn't + * distinguish between end-of-stream and an error, you should then use + * mio_eof() and mio_error() to determine which occurred. + */ +size_t mio_read (MIO *mio, + void *ptr_, + size_t size, + size_t nmemb) +{ + if (mio->type == MIO_TYPE_FILE) + return fread (ptr_, size, nmemb, mio->impl.file.fp); + else + { + size_t n_read = 0; + + if (size != 0 && nmemb != 0) + { + size_t size_avail = mio->impl.mem.size - mio->impl.mem.pos; + size_t copy_bytes = size * nmemb; + unsigned char *ptr = ptr_; + + if (size_avail < copy_bytes) + copy_bytes = size_avail; + + if (copy_bytes > 0) + { + n_read = copy_bytes / size; + + if (mio->impl.mem.ungetch != EOF) + { + *ptr = (unsigned char) mio->impl.mem.ungetch; + mio->impl.mem.ungetch = EOF; + copy_bytes--; + mio->impl.mem.pos++; + ptr++; + } + + memcpy (ptr, &mio->impl.mem.buf[mio->impl.mem.pos], copy_bytes); + mio->impl.mem.pos += copy_bytes; + } + if (mio->impl.mem.pos >= mio->impl.mem.size) + mio->impl.mem.eof = TRUE; + } + + return n_read; + } +} + +/* + * mem_try_resize: + * @mio: A #MIO object of the type %MIO_TYPE_MEMORY + * @new_size: Requested new size + * + * Tries to resize the underlying buffer of an in-memory #MIO object. + * This supports both growing and shrinking. + * + * Returns: %TRUE on success, %FALSE otherwise. + */ +static int mem_try_resize (MIO *mio, size_t new_size) +{ + int success = FALSE; + + if (mio->impl.mem.realloc_func) + { + if (new_size == ULONG_MAX) + { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#endif + } + else + { + if (new_size > mio->impl.mem.size) + { + if (new_size <= mio->impl.mem.allocated_size) + { + mio->impl.mem.size = new_size; + success = TRUE; + } + else + { + size_t newsize; + unsigned char *newbuf; + + newsize = MAX (mio->impl.mem.allocated_size + MIO_CHUNK_SIZE, + new_size); + newbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, newsize); + if (newbuf) + { + mio->impl.mem.buf = newbuf; + mio->impl.mem.allocated_size = newsize; + mio->impl.mem.size = new_size; + success = TRUE; + } + } + } + else + { + unsigned char *newbuf; + + newbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, new_size); + if (newbuf || new_size == 0) + { + mio->impl.mem.buf = newbuf; + mio->impl.mem.allocated_size = new_size; + mio->impl.mem.size = new_size; + success = TRUE; + } + } + } + } + + return success; +} + +/* + * mem_try_ensure_space: + * @mio: A #MIO object + * @n: Requested size from the current (cursor) position + * + * Tries to ensure there is enough space for @n bytes to be written from the + * current cursor position. + * + * Returns: %TRUE if there is enough space, %FALSE otherwise. + */ +static int mem_try_ensure_space (MIO *mio, size_t n) +{ + int success = TRUE; + + if (mio->impl.mem.pos + n > mio->impl.mem.size) + success = mem_try_resize (mio, mio->impl.mem.pos + n); + + return success; +} + +/** + * mio_write: + * @mio: A #MIO object + * @ptr: Pointer to the memory to write on the stream + * @size: Size of each block to write + * @nmemb: Number of block to write + * + * Writes raw data to a #MIO stream. This function behaves the same as fwrite(). + * + * Returns: The number of blocks actually written to the stream. This might be + * smaller than the requested count if a write error occurs. + */ +size_t mio_write (MIO *mio, + const void *ptr, + size_t size, + size_t nmemb) +{ + if (mio->type == MIO_TYPE_FILE) + return fwrite (ptr, size, nmemb, mio->impl.file.fp); + else + { + size_t n_written = 0; + + if (size != 0 && nmemb != 0) + { + if (mem_try_ensure_space (mio, size * nmemb)) + { + memcpy (&mio->impl.mem.buf[mio->impl.mem.pos], ptr, size * nmemb); + mio->impl.mem.pos += size * nmemb; + n_written = nmemb; + } + } + + return n_written; + } +} + +/** + * mio_putc: + * @mio: A #MIO object + * @c: The character to write + * + * Writes a character to a #MIO stream. This function behaves the same as + * fputc(). + * + * Returns: The written wharacter, or %EOF on error. + */ +int mio_putc (MIO *mio, int c) +{ + if (mio->type == MIO_TYPE_FILE) + return fputc (c, mio->impl.file.fp); + else + { + int rv = EOF; + + if (mem_try_ensure_space (mio, 1)) + { + mio->impl.mem.buf[mio->impl.mem.pos] = (unsigned char)c; + mio->impl.mem.pos++; + rv = (int)((unsigned char)c); + } + + return rv; + } +} + +/** + * mio_puts: + * @mio: A #MIO object + * @s: The string to write + * + * Writes a string to a #MIO object. This function behaves the same as fputs(). + * + * Returns: A non-negative integer on success or %EOF on failure. + */ +int mio_puts (MIO *mio, const char *s) +{ + if (mio->type == MIO_TYPE_FILE) + return fputs (s, mio->impl.file.fp); + else + { + int rv = EOF; + size_t len; + + len = strlen (s); + if (mem_try_ensure_space (mio, len)) + { + memcpy (&mio->impl.mem.buf[mio->impl.mem.pos], s, len); + mio->impl.mem.pos += len; + rv = 1; + } + + return rv; + } +} + +/** + * mio_vprintf: + * @mio: A #MIO object + * @format: A printf fomrat string + * @ap: The variadic argument list for the format + * + * Writes a formatted string into a #MIO stream. This function behaves the same + * as vfprintf(). + * + * Returns: The number of bytes written in the stream, or a negative value on + * failure. + */ +int mio_vprintf (MIO *mio, const char *format, va_list ap) +{ + if (mio->type == MIO_TYPE_FILE) + return vfprintf (mio->impl.file.fp, format, ap); + else + { + int rv = -1; + size_t n; + size_t old_pos; + size_t old_size; + va_list ap_copy; + char c; + + old_pos = mio->impl.mem.pos; + old_size = mio->impl.mem.size; + va_copy (ap_copy, ap); + /* compute the size we will need into the buffer */ + n = vsnprintf (&c, 1, format, ap_copy); + va_end (ap_copy); + if (mem_try_ensure_space (mio, n)) + { + unsigned char c; + + /* backup character at n+1 that will be overwritten by a \0 ... */ + c = mio->impl.mem.buf[mio->impl.mem.pos + (n - 1)]; + rv = vsprintf ((char *)&mio->impl.mem.buf[mio->impl.mem.pos], format, ap); + /* ...and restore it */ + mio->impl.mem.buf[mio->impl.mem.pos + (n - 1)] = c; + if (rv >= 0 && (size_t)rv == (n - 1)) + { + /* re-compute the actual size since we might have allocated one byte + * more than needed */ + mio->impl.mem.size = MAX (old_size, old_pos + (unsigned int)rv); + mio->impl.mem.pos += (unsigned int)rv; + } + else + { + mio->impl.mem.size = old_size; + rv = -1; + } + } + + return rv; + } +} + +/** + * mio_printf: + * @mio: A #MIO object + * @format: A print format string + * @...: Arguments of the format + * + * Writes a formatted string to a #MIO stream. This function behaves the same as + * fprintf(). + * + * Returns: The number of bytes written to the stream, or a negative value on + * failure. + */ +int mio_printf (MIO *mio, const char *format, ...) +{ + int rv; + va_list ap; + + va_start (ap, format); + rv = mio_vprintf (mio, format, ap); + va_end (ap); + + return rv; +} + +/** + * mio_getc: + * @mio: A #MIO object + * + * Gets the current character from a #MIO stream. This function behaves the same + * as fgetc(). + * + * Returns: The read character as a #int, or %EOF on error. + */ +int mio_getc (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + return fgetc (mio->impl.file.fp); + else + { + int rv = EOF; + + if (mio->impl.mem.ungetch != EOF) + { + rv = mio->impl.mem.ungetch; + mio->impl.mem.ungetch = EOF; + mio->impl.mem.pos++; + } + else if (mio->impl.mem.pos < mio->impl.mem.size) + { + rv = mio->impl.mem.buf[mio->impl.mem.pos]; + mio->impl.mem.pos++; + } + else + mio->impl.mem.eof = TRUE; + + return rv; + } +} + +/** + * mio_ungetc: + * @mio: A #MIO object + * @ch: Character to put back in the stream + * + * Puts a character back in a #MIO stream. This function behaves the sames as + * ungetc(). + * + * <warning><para>It is only guaranteed that one character can be but back at a + * time, even if the implementation may allow more.</para></warning> + * <warning><para>Using this function while the stream cursor is at offset 0 is + * not guaranteed to function properly. As the C99 standard says, it is "an + * obsolescent feature".</para></warning> + * + * Returns: The character put back, or %EOF on error. + */ +int mio_ungetc (MIO *mio, int ch) +{ + if (mio->type == MIO_TYPE_FILE) + return ungetc (ch, mio->impl.file.fp); + else + { + int rv = EOF; + + if (ch != EOF && mio->impl.mem.ungetch == EOF) + { + rv = mio->impl.mem.ungetch = ch; + mio->impl.mem.pos--; + mio->impl.mem.eof = FALSE; + } + + return rv; + } +} + +/** + * mio_gets: + * @mio: A #MIO object + * @s: A string to fill with the read data + * @size: The maximum number of bytes to read + * + * Reads a string from a #MIO stream, stopping after the first new-line + * character or at the end of the stream. This function behaves the same as + * fgets(). + * + * Returns: @s on success, %NULL otherwise. + */ +char *mio_gets (MIO *mio, char *s, size_t size) +{ + if (mio->type == MIO_TYPE_FILE) + return fgets (s, (int)size, mio->impl.file.fp); + else + { + char *rv = NULL; + + if (size > 0) + { + size_t i = 0; + + if (mio->impl.mem.ungetch != EOF) + { + s[i] = (char)mio->impl.mem.ungetch; + mio->impl.mem.ungetch = EOF; + mio->impl.mem.pos++; + i++; + } + for (; mio->impl.mem.pos < mio->impl.mem.size && i < (size - 1); i++) + { + s[i] = (char)mio->impl.mem.buf[mio->impl.mem.pos]; + mio->impl.mem.pos++; + if (s[i] == '\n') + { + i++; + break; + } + } + if (i > 0) + { + s[i] = 0; + rv = s; + } + if (mio->impl.mem.pos >= mio->impl.mem.size) + mio->impl.mem.eof = TRUE; + } + + return rv; + } +} + +/** + * mio_clearerr: + * @mio: A #MIO object + * + * Clears the error and end-of-stream indicators of a #MIO stream. This function + * behaves the same as clearerr(). + */ +void mio_clearerr (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + clearerr (mio->impl.file.fp); + else + { + mio->impl.mem.error = FALSE; + mio->impl.mem.eof = FALSE; + } +} + +/** + * mio_eof: + * @mio: A #MIO object + * + * Checks whether the end-of-stream indicator of a #MIO stream is set. This + * function behaves the same as feof(). + * + * Returns: A non-null value if the stream reached its end, 0 otherwise. + */ +int mio_eof (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + return feof (mio->impl.file.fp); + else + return mio->impl.mem.eof != FALSE; +} + +/** + * mio_error: + * @mio: A #MIO object + * + * Checks whether the error indicator of a #MIO stream is set. This function + * behaves the same as ferror(). + * + * Returns: A non-null value if the stream have an error set, 0 otherwise. + */ +int mio_error (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + return ferror (mio->impl.file.fp); + else + return mio->impl.mem.error != FALSE; +} + +/** + * mio_seek: + * @mio: A #MIO object + * @offset: Offset of the new place, from @whence + * @whence: Move origin. SEEK_SET moves relative to the start of the stream, + * SEEK_CUR from the current position and SEEK_SET from the end of the + * stream. + * + * Sets the curosr position on a #MIO stream. This functions behaves the same as + * fseek(). See also mio_tell() and mio_setpos(). + * + * Returns: 0 on success, -1 otherwise, in which case errno should be set to + * indicate the error. + */ +int mio_seek (MIO *mio, long offset, int whence) +{ + if (mio->type == MIO_TYPE_FILE) + return fseek (mio->impl.file.fp, offset, whence); + else + { + /* FIXME: should we support seeking out of bounds like lseek() seems to do? */ + int rv = -1; + + switch (whence) + { + case SEEK_SET: + if (offset < 0 || (size_t)offset > mio->impl.mem.size) + errno = EINVAL; + else + { + mio->impl.mem.pos = (size_t)offset; + rv = 0; + } + break; + + case SEEK_CUR: + if ((offset < 0 && (size_t)-offset > mio->impl.mem.pos) || + mio->impl.mem.pos + (size_t)offset > mio->impl.mem.size) + { + errno = EINVAL; + } + else + { + mio->impl.mem.pos = (size_t)(mio->impl.mem.pos + offset); + rv = 0; + } + break; + + case SEEK_END: + if (offset > 0 || (size_t)-offset > mio->impl.mem.size) + errno = EINVAL; + else + { + mio->impl.mem.pos = mio->impl.mem.size - (size_t)-offset; + rv = 0; + } + break; + + default: + errno = EINVAL; + } + if (rv == 0) + { + mio->impl.mem.eof = FALSE; + mio->impl.mem.ungetch = EOF; + } + + return rv; + } +} + +/** + * mio_tell: + * @mio: A #MIO object + * + * Gets the current cursor position of a #MIO stream. This function behaves the + * same as ftell(). + * + * Returns: The current offset from the start of the stream, or -1 or error, in + * which case errno is set to indicate the error. + */ +long mio_tell (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + return ftell (mio->impl.file.fp); + else + { + long rv = -1; + + if (mio->impl.mem.pos > LONG_MAX) + { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#endif + } + else + rv = (long)mio->impl.mem.pos; + + return rv; + } +} + +/** + * mio_rewind: + * @mio: A #MIO object + * + * Resets the cursor position to 0, and also the end-of-stream and the error + * indicators of a #MIO stream. + * See also mio_seek() and mio_clearerr(). + */ +void mio_rewind (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + rewind (mio->impl.file.fp); + else + { + mio->impl.mem.pos = 0; + mio->impl.mem.ungetch = EOF; + mio->impl.mem.eof = FALSE; + mio->impl.mem.error = FALSE; + } +} + +/** + * mio_getpos: + * @mio: A #MIO stream + * @pos: (out): A #MIOPos object to fill-in + * + * Stores the current position (and maybe other informations about the stream + * state) of a #MIO stream in order to restore it later with mio_setpos(). This + * function behaves the same as fgetpos(). + * + * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate + * the error. + */ +int mio_getpos (MIO *mio, MIOPos *pos) +{ + int rv = -1; + + pos->type = mio->type; + if (mio->type == MIO_TYPE_FILE) + rv = fgetpos (mio->impl.file.fp, &pos->impl.file); + else + { + rv = -1; + + if (mio->impl.mem.pos == (size_t)-1) + { + /* this happens if ungetc() was called at the start of the stream */ +#ifdef EIO + errno = EIO; +#endif + } + else + { + pos->impl.mem = mio->impl.mem.pos; + rv = 0; + } + } +#ifdef MIO_DEBUG + if (rv != -1) + { + pos->tag = mio; + } +#endif /* MIO_DEBUG */ + + return rv; +} + +/** + * mio_setpos: + * @mio: A #MIO object + * @pos: (in): A #MIOPos object filled-in by a previous call of mio_getpos() on + * the same stream + * + * Restores the position and state indicators of a #MIO stream previously saved + * by mio_getpos(). + * + * <warning><para>The #MIOPos object must have been initialized by a previous + * call to mio_getpos() on the same stream.</para></warning> + * + * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate + * the error. + */ +int mio_setpos (MIO *mio, MIOPos *pos) +{ + int rv = -1; + +#ifdef MIO_DEBUG + if (pos->tag != mio) + { + g_critical ("mio_setpos((MIO*)%p, (MIOPos*)%p): " + "Given MIOPos was not set by a previous call to mio_getpos() " + "on the same MIO object, which means there is a bug in " + "someone's code.", + (void *)mio, (void *)pos); + errno = EINVAL; + return -1; + } +#endif /* MIO_DEBUG */ + + if (mio->type == MIO_TYPE_FILE) + rv = fsetpos (mio->impl.file.fp, &pos->impl.file); + else + { + rv = -1; + + if (pos->impl.mem > mio->impl.mem.size) + errno = EINVAL; + else + { + mio->impl.mem.ungetch = EOF; + mio->impl.mem.pos = pos->impl.mem; + rv = 0; + } + } + + return rv; +} + +/** + * mio_flush: + * @mio: A #MIO object + * + * Forces a write of all user-space buffered data for the given output or update + * stream via the stream's underlying write function. Only applicable when using + * FILE back-end. + * + * Returns: 0 on success, error code otherwise. + */ +int mio_flush (MIO *mio) +{ + if (mio->type == MIO_TYPE_FILE) + return fflush (mio->impl.file.fp); + return 0; +}
Modified: ctags/main/mio.h 178 lines changed, 178 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,178 @@ +/* + * MIO, an I/O abstraction layer replicating C file I/O API. + * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef MIO_H +#define MIO_H + +#include "general.h" /* must always come first */ + +#include <stdio.h> +#include <stdarg.h> + + +/** + * MIOType: + * @MIO_TYPE_FILE: #MIO object works on a file + * @MIO_TYPE_MEMORY: #MIO object works in-memory + * + * Existing implementations. + */ +enum _MIOType { + MIO_TYPE_FILE, + MIO_TYPE_MEMORY +}; + +typedef enum _MIOType MIOType; +typedef struct _MIO MIO; +typedef struct _MIOPos MIOPos; + +/** + * MIOReallocFunc: + * @ptr: Pointer to the memory to resize + * @size: New size of the memory pointed by @ptr + * + * A function following the realloc() semantic. + * + * Returns: A pointer to the start of the new memory, or %NULL on failure. + */ +typedef void *(* MIOReallocFunc) (void * ptr, size_t size); + +/** + * MIOFOpenFunc: + * @filename: The filename to open + * @mode: fopen() modes for opening @filename + * + * A function following the fclose() semantic, used to close a #FILE + * object. + * + * Returns: A new #FILE object, or %NULL on failure + */ +typedef FILE *(* MIOFOpenFunc) (const char *filename, const char *mode); + +/** + * MIOFCloseFunc: + * @fp: An opened #FILE object + * + * A function following the fclose() semantic, used to close a #FILE + * object. + * + * Returns: 0 on success, EOF otherwise. + */ +typedef int (* MIOFCloseFunc) (FILE *fp); + +/** + * MIODestroyNotify: + * @data: Data element being destroyed + * + * Specifies the type of function which is called when a data element is + * destroyed. It is passed the pointer to the data element and should free any + * memory and resources allocated for it. + */ +typedef void (*MIODestroyNotify) (void *data); + +/** + * MIOPos: + * + * An object representing the state of a #MIO stream. This object can be + * statically allocated but all its fields are private and should not be + * accessed directly. + */ +struct _MIOPos { + /*< private >*/ + unsigned int type; +#ifdef MIO_DEBUG + void *tag; +#endif + union { + fpos_t file; + size_t mem; + } impl; +}; + +/** + * MIO: + * + * An object representing a #MIO stream. No assumptions should be made about + * what compose this object, and none of its fields should be accessed directly. + */ +struct _MIO { + /*< private >*/ + unsigned int type; + union { + struct { + FILE *fp; + MIOFCloseFunc close_func; + } file; + struct { + unsigned char *buf; + int ungetch; + size_t pos; + size_t size; + size_t allocated_size; + MIOReallocFunc realloc_func; + MIODestroyNotify free_func; + boolean error; + boolean eof; + } mem; + } impl; +}; + + +MIO *mio_new_file (const char *filename, const char *mode); +MIO *mio_new_file_full (const char *filename, + const char *mode, + MIOFOpenFunc open_func, + MIOFCloseFunc close_func); +MIO *mio_new_fp (FILE *fp, MIOFCloseFunc close_func); +MIO *mio_new_memory (unsigned char *data, + size_t size, + MIOReallocFunc realloc_func, + MIODestroyNotify free_func); +int mio_free (MIO *mio); +FILE *mio_file_get_fp (MIO *mio); +unsigned char *mio_memory_get_data (MIO *mio, size_t *size); +size_t mio_read (MIO *mio, + void *ptr, + size_t size, + size_t nmemb); +size_t mio_write (MIO *mio, + const void *ptr, + size_t size, + size_t nmemb); +int mio_getc (MIO *mio); +char *mio_gets (MIO *mio, char *s, size_t size); +int mio_ungetc (MIO *mio, int ch); +int mio_putc (MIO *mio, int c); +int mio_puts (MIO *mio, const char *s); + +int mio_vprintf (MIO *mio, const char *format, va_list ap) PRINTF (2, 0); +int mio_printf (MIO *mio, const char *format, ...) PRINTF (2, 3); + +void mio_clearerr (MIO *mio); +int mio_eof (MIO *mio); +int mio_error (MIO *mio); +int mio_seek (MIO *mio, long offset, int whence); +long mio_tell (MIO *mio); +void mio_rewind (MIO *mio); +int mio_getpos (MIO *mio, MIOPos *pos); +int mio_setpos (MIO *mio, MIOPos *pos); +int mio_flush (MIO *mio); + +#endif /* MIO_H */
Modified: ctags/main/parse.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -15,9 +15,9 @@ #include "general.h" /* must always come first */
#include <string.h> -#include <mio/mio.h>
+#include "mio.h" #include "entry.h" #include "main.h" #define OPTION_WRITE
Modified: ctags/main/read.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -17,8 +17,8 @@
#include <stdio.h> #include <ctype.h> -#include <mio/mio.h>
+#include "mio.h" #include "parse.h" #include "vstring.h"
Modified: ctags/mio/COPYING 339 lines changed, 0 insertions(+), 339 deletions(-) =================================================================== @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program 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 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License.
Modified: ctags/mio/Makefile.am 13 lines changed, 0 insertions(+), 13 deletions(-) =================================================================== @@ -1,13 +0,0 @@ -noinst_LTLIBRARIES = libmio.la - -AM_CPPFLAGS = -DG_LOG_DOMAIN="MIO" #-DMIO_DEBUG -AM_CFLAGS = $(GTK_CFLAGS) @LIBGEANY_CFLAGS@ - -libmio_la_LIBADD = $(GTK_LIBS) -libmio_la_SOURCES = mio.c - -EXTRA_DIST = \ - mio.h \ - mio-file.c \ - mio-memory.c \ - makefile.win32
Modified: ctags/mio/README 3 lines changed, 0 insertions(+), 3 deletions(-) =================================================================== @@ -1,3 +0,0 @@ -These files are from the MIO library, http://gitorious.org/mio - -See COPYING for the MIO license.
Modified: ctags/mio/makefile.win32 53 lines changed, 0 insertions(+), 53 deletions(-) =================================================================== @@ -1,53 +0,0 @@ - -.SUFFIXES: .cxx .c .o .h .a -CC = gcc -AR = ar -RANLIB = ranlib -PREFIX = C:/libs -RM = del --include ../../localwin32.mk - -ifdef MSYS -RM = rm -f -endif - -COMPLIB=mio.a - -GTK_INCLUDES= \ - -I$(PREFIX)/include/gtk-2.0 \ - -I$(PREFIX)/lib/gtk-2.0/include \ - -I$(PREFIX)/include/atk-1.0 \ - -I$(PREFIX)/include/cairo \ - -I$(PREFIX)/include/gdk-pixbuf-2.0 \ - -I$(PREFIX)/include/pango-1.0 \ - -I$(PREFIX)/include/glib-2.0 \ - -I$(PREFIX)/lib/glib-2.0/include \ - -I$(PREFIX)/include \ - -I$(PREFIX)/include/gettext - -INCLUDEDIRS=-I include $(GTK_INCLUDES) - -CBASEFLAGS=-Wall -pipe -mms-bitfields -DPACKAGE="geany" -Wno-missing-braces -Wno-char-subscripts $(INCLUDEDIRS) -ifdef DEBUG -CFLAGS= -O0 -g $(CBASEFLAGS) -else -CFLAGS=-O2 $(CBASEFLAGS) -endif - -.c.o: - $(CC) $(CFLAGS) -c $< - -all: $(COMPLIB) - -clean: - -$(RM) deps.mak *.o $(COMPLIB) - -$(COMPLIB): mio.o - $(AR) rc $@ $^ - $(RANLIB) $@ - -deps.mak: - $(CC) -MM $(CFLAGS) *.c >deps.mak - -# Generate header dependencies with "make deps.mak" -include deps.mak
Modified: ctags/mio/mio-file.c 175 lines changed, 0 insertions(+), 175 deletions(-) =================================================================== @@ -1,175 +0,0 @@ -/* - * MIO, an I/O abstraction layer replicating C file I/O API. - * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/* file IO implementation */ - -#include <glib.h> -#include <stdarg.h> -#include <stdio.h> -#include <errno.h> - -#include "mio.h" - - -#define FILE_SET_VTABLE(mio) \ - G_STMT_START { \ - mio->v_free = file_free; \ - mio->v_read = file_read; \ - mio->v_write = file_write; \ - mio->v_getc = file_getc; \ - mio->v_gets = file_gets; \ - mio->v_ungetc = file_ungetc; \ - mio->v_putc = file_putc; \ - mio->v_puts = file_puts; \ - mio->v_vprintf = file_vprintf; \ - mio->v_clearerr = file_clearerr; \ - mio->v_eof = file_eof; \ - mio->v_error = file_error; \ - mio->v_seek = file_seek; \ - mio->v_tell = file_tell; \ - mio->v_rewind = file_rewind; \ - mio->v_getpos = file_getpos; \ - mio->v_setpos = file_setpos; \ - } G_STMT_END - - -static void -file_free (MIO *mio) -{ - if (mio->impl.file.close_func) { - mio->impl.file.close_func (mio->impl.file.fp); - } - mio->impl.file.close_func = NULL; - mio->impl.file.fp = NULL; -} - -static gsize -file_read (MIO *mio, - void *ptr, - gsize size, - gsize nmemb) -{ - return fread (ptr, size, nmemb, mio->impl.file.fp); -} - -static gsize -file_write (MIO *mio, - const void *ptr, - gsize size, - gsize nmemb) -{ - return fwrite (ptr, size, nmemb, mio->impl.file.fp); -} - -static gint -file_putc (MIO *mio, - gint c) -{ - return fputc (c, mio->impl.file.fp); -} - -static gint -file_puts (MIO *mio, - const gchar *s) -{ - return fputs (s, mio->impl.file.fp); -} - -G_GNUC_PRINTF (2, 0) -static gint -file_vprintf (MIO *mio, - const gchar *format, - va_list ap) -{ - return vfprintf (mio->impl.file.fp, format, ap); -} - -static gint -file_getc (MIO *mio) -{ - return fgetc (mio->impl.file.fp); -} - -static gint -file_ungetc (MIO *mio, - gint ch) -{ - return ungetc (ch, mio->impl.file.fp); -} - -static gchar * -file_gets (MIO *mio, - gchar *s, - gsize size) -{ - return fgets (s, (int)size, mio->impl.file.fp); -} - -static void -file_clearerr (MIO *mio) -{ - clearerr (mio->impl.file.fp); -} - -static gint -file_eof (MIO *mio) -{ - return feof (mio->impl.file.fp); -} - -static gint -file_error (MIO *mio) -{ - return ferror (mio->impl.file.fp); -} - -static gint -file_seek (MIO *mio, - glong offset, - gint whence) -{ - return fseek (mio->impl.file.fp, offset, whence); -} - -static glong -file_tell (MIO *mio) -{ - return ftell (mio->impl.file.fp); -} - -static void -file_rewind (MIO *mio) -{ - rewind (mio->impl.file.fp); -} - -static gint -file_getpos (MIO *mio, - MIOPos *pos) -{ - return fgetpos (mio->impl.file.fp, &pos->impl.file); -} - -static gint -file_setpos (MIO *mio, - MIOPos *pos) -{ - return fsetpos (mio->impl.file.fp, &pos->impl.file); -}
Modified: ctags/mio/mio-memory.c 480 lines changed, 0 insertions(+), 480 deletions(-) =================================================================== @@ -1,480 +0,0 @@ -/* - * MIO, an I/O abstraction layer replicating C file I/O API. - * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/* memory IO implementation */ - -#include <glib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "mio.h" - - -#define MEM_SET_VTABLE(mio) \ - G_STMT_START { \ - mio->v_free = mem_free; \ - mio->v_read = mem_read; \ - mio->v_write = mem_write; \ - mio->v_getc = mem_getc; \ - mio->v_gets = mem_gets; \ - mio->v_ungetc = mem_ungetc; \ - mio->v_putc = mem_putc; \ - mio->v_puts = mem_puts; \ - mio->v_vprintf = mem_vprintf; \ - mio->v_clearerr = mem_clearerr; \ - mio->v_eof = mem_eof; \ - mio->v_error = mem_error; \ - mio->v_seek = mem_seek; \ - mio->v_tell = mem_tell; \ - mio->v_rewind = mem_rewind; \ - mio->v_getpos = mem_getpos; \ - mio->v_setpos = mem_setpos; \ - } G_STMT_END - - -/* minimal reallocation chunk size */ -#define MIO_CHUNK_SIZE 4096 - - -static void -mem_free (MIO *mio) -{ - if (mio->impl.mem.free_func) { - mio->impl.mem.free_func (mio->impl.mem.buf); - } - mio->impl.mem.buf = NULL; - mio->impl.mem.pos = 0; - mio->impl.mem.size = 0; - mio->impl.mem.allocated_size = 0; - mio->impl.mem.realloc_func = NULL; - mio->impl.mem.free_func = NULL; - mio->impl.mem.eof = FALSE; - mio->impl.mem.error = FALSE; -} - -static gsize -mem_read (MIO *mio, - void *ptr_, - gsize size, - gsize nmemb) -{ - gsize n_read = 0; - - if (size != 0 && nmemb != 0) { - gsize size_avail = mio->impl.mem.size - mio->impl.mem.pos; - gsize copy_bytes = size * nmemb; - guchar *ptr = ptr_; - - if (size_avail < copy_bytes) { - copy_bytes = size_avail; - } - - if (copy_bytes > 0) { - n_read = copy_bytes / size; - - if (mio->impl.mem.ungetch != EOF) { - *ptr = (guchar) mio->impl.mem.ungetch; - mio->impl.mem.ungetch = EOF; - copy_bytes--; - mio->impl.mem.pos++; - ptr++; - } - - memcpy (ptr, &mio->impl.mem.buf[mio->impl.mem.pos], copy_bytes); - mio->impl.mem.pos += copy_bytes; - } - if (mio->impl.mem.pos >= mio->impl.mem.size) { - mio->impl.mem.eof = TRUE; - } - } - - return n_read; -} - -/* - * mem_try_resize: - * @mio: A #MIO object of the type %MIO_TYPE_MEMORY - * @new_size: Requested new size - * - * Tries to resize the underlying buffer of an in-memory #MIO object. - * This supports both growing and shrinking. - * - * Returns: %TRUE on success, %FALSE otherwise. - */ -static gboolean -mem_try_resize (MIO *mio, - gsize new_size) -{ - gboolean success = FALSE; - - if (mio->impl.mem.realloc_func) { - if (G_UNLIKELY (new_size == G_MAXSIZE)) { - #ifdef EOVERFLOW - errno = EOVERFLOW; - #endif - } else { - if (new_size > mio->impl.mem.size) { - if (new_size <= mio->impl.mem.allocated_size) { - mio->impl.mem.size = new_size; - success = TRUE; - } else { - gsize newsize; - guchar *newbuf; - - newsize = MAX (mio->impl.mem.allocated_size + MIO_CHUNK_SIZE, - new_size); - newbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, newsize); - if (newbuf) { - mio->impl.mem.buf = newbuf; - mio->impl.mem.allocated_size = newsize; - mio->impl.mem.size = new_size; - success = TRUE; - } - } - } else { - guchar *newbuf; - - newbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, new_size); - if (G_LIKELY (newbuf || new_size == 0)) { - mio->impl.mem.buf = newbuf; - mio->impl.mem.allocated_size = new_size; - mio->impl.mem.size = new_size; - success = TRUE; - } - } - } - } - - return success; -} - -/* - * mem_try_ensure_space: - * @mio: A #MIO object - * @n: Requested size from the current (cursor) position - * - * Tries to ensure there is enough space for @n bytes to be written from the - * current cursor position. - * - * Returns: %TRUE if there is enough space, %FALSE otherwise. - */ -static gboolean -mem_try_ensure_space (MIO *mio, - gsize n) -{ - gboolean success = TRUE; - - if (mio->impl.mem.pos + n > mio->impl.mem.size) { - success = mem_try_resize (mio, mio->impl.mem.pos + n); - } - - return success; -} - -static gsize -mem_write (MIO *mio, - const void *ptr, - gsize size, - gsize nmemb) -{ - gsize n_written = 0; - - if (size != 0 && nmemb != 0) { - if (mem_try_ensure_space (mio, size * nmemb)) { - memcpy (&mio->impl.mem.buf[mio->impl.mem.pos], ptr, size * nmemb); - mio->impl.mem.pos += size * nmemb; - n_written = nmemb; - } - } - - return n_written; -} - -static gint -mem_putc (MIO *mio, - gint c) -{ - gint rv = EOF; - - if (mem_try_ensure_space (mio, 1)) { - mio->impl.mem.buf[mio->impl.mem.pos] = (guchar)c; - mio->impl.mem.pos++; - rv = (gint)((guchar)c); - } - - return rv; -} - -static gint -mem_puts (MIO *mio, - const gchar *s) -{ - gint rv = EOF; - gsize len; - - len = strlen (s); - if (mem_try_ensure_space (mio, len)) { - memcpy (&mio->impl.mem.buf[mio->impl.mem.pos], s, len); - mio->impl.mem.pos += len; - rv = 1; - } - - return rv; -} - -G_GNUC_PRINTF (2, 0) -static gint -mem_vprintf (MIO *mio, - const gchar *format, - va_list ap) -{ - gint rv = -1; - gsize n; - gsize old_pos; - gsize old_size; - va_list ap_copy; - - old_pos = mio->impl.mem.pos; - old_size = mio->impl.mem.size; - G_VA_COPY (ap_copy, ap); - /* compute the size we will need into the buffer */ - n = g_printf_string_upper_bound (format, ap_copy); - va_end (ap_copy); - if (mem_try_ensure_space (mio, n)) { - guchar c; - - /* backup character at n+1 that will be overwritten by a \0 ... */ - c = mio->impl.mem.buf[mio->impl.mem.pos + (n - 1)]; - rv = vsprintf ((gchar *)&mio->impl.mem.buf[mio->impl.mem.pos], format, ap); - /* ...and restore it */ - mio->impl.mem.buf[mio->impl.mem.pos + (n - 1)] = c; - if (G_LIKELY (rv >= 0 && (gsize)rv == (n - 1))) { - /* re-compute the actual size since we might have allocated one byte - * more than needed */ - mio->impl.mem.size = MAX (old_size, old_pos + (guint)rv); - mio->impl.mem.pos += (guint)rv; - } else { - mio->impl.mem.size = old_size; - rv = -1; - } - } - - return rv; -} - -static gint -mem_getc (MIO *mio) -{ - gint rv = EOF; - - if (mio->impl.mem.ungetch != EOF) { - rv = mio->impl.mem.ungetch; - mio->impl.mem.ungetch = EOF; - mio->impl.mem.pos++; - } else if (mio->impl.mem.pos < mio->impl.mem.size) { - rv = mio->impl.mem.buf[mio->impl.mem.pos]; - mio->impl.mem.pos++; - } else { - mio->impl.mem.eof = TRUE; - } - - return rv; -} - -static gint -mem_ungetc (MIO *mio, - gint ch) -{ - gint rv = EOF; - - if (ch != EOF && mio->impl.mem.ungetch == EOF) { - rv = mio->impl.mem.ungetch = ch; - mio->impl.mem.pos--; - mio->impl.mem.eof = FALSE; - } - - return rv; -} - -static gchar * -mem_gets (MIO *mio, - gchar *s, - gsize size) -{ - gchar *rv = NULL; - - if (size > 0) { - gsize i = 0; - - if (mio->impl.mem.ungetch != EOF) { - s[i] = (gchar)mio->impl.mem.ungetch; - mio->impl.mem.ungetch = EOF; - mio->impl.mem.pos++; - i++; - } - for (; mio->impl.mem.pos < mio->impl.mem.size && i < (size - 1); i++) { - s[i] = (gchar)mio->impl.mem.buf[mio->impl.mem.pos]; - mio->impl.mem.pos++; - if (s[i] == '\n') { - i++; - break; - } - } - if (i > 0) { - s[i] = 0; - rv = s; - } - if (mio->impl.mem.pos >= mio->impl.mem.size) { - mio->impl.mem.eof = TRUE; - } - } - - return rv; -} - -static void -mem_clearerr (MIO *mio) -{ - mio->impl.mem.error = FALSE; - mio->impl.mem.eof = FALSE; -} - -static gint -mem_eof (MIO *mio) -{ - return mio->impl.mem.eof != FALSE; -} - -static gint -mem_error (MIO *mio) -{ - return mio->impl.mem.error != FALSE; -} - -/* FIXME: should we support seeking out of bounds like lseek() seems to do? */ -static gint -mem_seek (MIO *mio, - glong offset, - gint whence) -{ - gint rv = -1; - - switch (whence) { - case SEEK_SET: - if (offset < 0 || (gsize)offset > mio->impl.mem.size) { - errno = EINVAL; - } else { - mio->impl.mem.pos = (gsize)offset; - rv = 0; - } - break; - - case SEEK_CUR: - if ((offset < 0 && (gsize)-offset > mio->impl.mem.pos) || - mio->impl.mem.pos + (gsize)offset > mio->impl.mem.size) { - errno = EINVAL; - } else { - mio->impl.mem.pos = (gsize)((gssize)mio->impl.mem.pos + offset); - rv = 0; - } - break; - - case SEEK_END: - if (offset > 0 || (gsize)-offset > mio->impl.mem.size) { - errno = EINVAL; - } else { - mio->impl.mem.pos = mio->impl.mem.size - (gsize)-offset; - rv = 0; - } - break; - - default: - errno = EINVAL; - } - if (rv == 0) { - mio->impl.mem.eof = FALSE; - mio->impl.mem.ungetch = EOF; - } - - return rv; -} - -static glong -mem_tell (MIO *mio) -{ - glong rv = -1; - - if (mio->impl.mem.pos > G_MAXLONG) { - #ifdef EOVERFLOW - errno = EOVERFLOW; - #endif - } else { - rv = (glong)mio->impl.mem.pos; - } - - return rv; -} - -static void -mem_rewind (MIO *mio) -{ - mio->impl.mem.pos = 0; - mio->impl.mem.ungetch = EOF; - mio->impl.mem.eof = FALSE; - mio->impl.mem.error = FALSE; -} - -static gint -mem_getpos (MIO *mio, - MIOPos *pos) -{ - gint rv = -1; - - if (mio->impl.mem.pos == (gsize)-1) { - /* this happens if ungetc() was called at the start of the stream */ - #ifdef EIO - errno = EIO; - #endif - } else { - pos->impl.mem = mio->impl.mem.pos; - rv = 0; - } - - return rv; -} - -static gint -mem_setpos (MIO *mio, - MIOPos *pos) -{ - gint rv = -1; - - if (pos->impl.mem > mio->impl.mem.size) { - errno = EINVAL; - } else { - mio->impl.mem.ungetch = EOF; - mio->impl.mem.pos = pos->impl.mem; - rv = 0; - } - - return rv; -}
Modified: ctags/mio/mio.c 656 lines changed, 0 insertions(+), 656 deletions(-) =================================================================== @@ -1,656 +0,0 @@ -/* - * MIO, an I/O abstraction layer replicating C file I/O API. - * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/* Hack to force ANSI compliance by not using va_copy() even if present. - * This relies on the fact G_VA_COPY is maybe defined as va_copy in - * glibconfig.h, so we undef it, but gutils.h takes care of defining a - * compiler-specific implementation if not already defined. - * This needs to come before any other GLib inclusion. */ -#ifdef MIO_FORCE_ANSI -# include <glibconfig.h> -# undef G_VA_COPY -#endif - -#include "mio.h" -#include "mio-file.c" -#include "mio-memory.c" - -#include <glib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - - - -/** - * SECTION:mio - * @short_description: The MIO object - * @include: mio/mio.h - * - * The #MIO object replicates the C file I/O API with support of both standard - * file based operations and in-memory operations. Its goal is to ease the port - * of an application that uses C file I/O API to perform in-memory operations. - * - * A #MIO object is created using mio_new_file() or mio_new_memory(), depending - * on whether you want file or in-memory operations, and destroyed using - * mio_free(). There is also some other convenient API to create file-based - * #MIO objects for more complex cases, such as mio_new_file_full() and - * mio_new_fp(). - * - * Once the #MIO object is created, you can perform standard I/O operations on - * it transparently without the need to care about the effective underlying - * operations. - * - * The I/O API is almost exactly a replication of the standard C file I/O API - * with the significant difference that the first parameter is always the #MIO - * object to work on. - */ - - -/** - * mio_new_file_full: - * @filename: Filename to open, passed as-is to @open_func as the first argument - * @mode: Mode in which open the file, passed as-is to @open_func as the second - * argument - * @open_func: A function with the fopen() semantic to use to open the file - * @close_func: A function with the fclose() semantic to close the file when - * the #MIO object is destroyed, or %NULL not to close the #FILE - * object - * - * Creates a new #MIO object working on a file, from a filename and an opening - * function. See also mio_new_file(). - * - * This function is generally overkill and mio_new_file() should often be used - * instead, but it allows to specify a custom function to open a file, as well - * as a close function. The former is useful e.g. if you need to wrap fopen() - * for some reason (like filename encoding conversion for example), and the - * latter allows you both to match your custom open function and to choose - * whether the underlying #FILE object should or not be closed when mio_free() - * is called on the returned object. - * - * Free-function: mio_free() - * - * Returns: A new #MIO on success, or %NULL on failure. - */ -MIO * -mio_new_file_full (const gchar *filename, - const gchar *mode, - MIOFOpenFunc open_func, - MIOFCloseFunc close_func) -{ - MIO *mio; - - /* we need to create the MIO object first, because we may not be able to close - * the opened file if the user passed NULL as the close function, which means - * that everything must succeed if we've opened the file successfully */ - mio = g_slice_alloc (sizeof *mio); - if (mio) { - FILE *fp = open_func (filename, mode); - - if (! fp) { - g_slice_free1 (sizeof *mio, mio); - mio = NULL; - } else { - mio->type = MIO_TYPE_FILE; - mio->impl.file.fp = fp; - mio->impl.file.close_func = close_func; - /* function table filling */ - FILE_SET_VTABLE (mio); - } - } - - return mio; -} - -/** - * mio_new_file: - * @filename: Filename to open, same as the fopen()'s first argument - * @mode: Mode in which open the file, fopen()'s second argument - * - * Creates a new #MIO object working on a file from a filename; wrapping - * fopen(). - * This function simply calls mio_new_file_full() with the libc's fopen() and - * fclose() functions. - * - * Free-function: mio_free() - * - * Returns: A new #MIO on success, or %NULL on failure. - */ -MIO * -mio_new_file (const gchar *filename, - const gchar *mode) -{ - return mio_new_file_full (filename, mode, fopen, fclose); -} - -/** - * mio_new_fp: - * @fp: An opened #FILE object - * @close_func: (allow-none): Function used to close @fp when the #MIO object - * gets destroyed, or %NULL not to close the #FILE object - * - * Creates a new #MIO object working on a file, from an already opened #FILE - * object. - * - * <example> - * <title>Typical use of this function</title> - * <programlisting> - * MIO *mio = mio_new_fp (fp, fclose); - * </programlisting> - * </example> - * - * Free-function: mio_free() - * - * Returns: A new #MIO on success or %NULL on failure. - */ -MIO * -mio_new_fp (FILE *fp, - MIOFCloseFunc close_func) -{ - MIO *mio; - - mio = g_slice_alloc (sizeof *mio); - if (mio) { - mio->type = MIO_TYPE_FILE; - mio->impl.file.fp = fp; - mio->impl.file.close_func = close_func; - /* function table filling */ - FILE_SET_VTABLE (mio); - } - - return mio; -} - -/** - * mio_new_memory: - * @data: Initial data (may be %NULL) - * @size: Length of @data in bytes - * @realloc_func: A function with the realloc() semantic used to grow the - * buffer, or %NULL to disable buffer growing - * @free_func: A function with the free() semantic to destroy the data together - * with the object, or %NULL not to destroy the data - * - * Creates a new #MIO object working on memory. - * - * To allow the buffer to grow, you must provide a @realloc_func, otherwise - * trying to write after the end of the current data will fail. - * - * If you want the buffer to be freed together with the #MIO object, you must - * give a @free_func; otherwise the data will still live after #MIO object - * termination. - * - * <example> - * <title>Basic creation of a non-growable, freeable #MIO object</title> - * <programlisting> - * MIO *mio = mio_new_memory (data, size, NULL, g_free); - * </programlisting> - * </example> - * - * <example> - * <title>Basic creation of an empty growable and freeable #MIO object</title> - * <programlisting> - * MIO *mio = mio_new_memory (NULL, 0, g_try_realloc, g_free); - * </programlisting> - * </example> - * - * Free-function: mio_free() - * - * Returns: A new #MIO on success, or %NULL on failure. - */ -MIO * -mio_new_memory (guchar *data, - gsize size, - MIOReallocFunc realloc_func, - GDestroyNotify free_func) -{ - MIO *mio; - - mio = g_slice_alloc (sizeof *mio); - if (mio) { - mio->type = MIO_TYPE_MEMORY; - mio->impl.mem.buf = data; - mio->impl.mem.ungetch = EOF; - mio->impl.mem.pos = 0; - mio->impl.mem.size = size; - mio->impl.mem.allocated_size = size; - mio->impl.mem.realloc_func = realloc_func; - mio->impl.mem.free_func = free_func; - mio->impl.mem.eof = FALSE; - mio->impl.mem.error = FALSE; - /* function table filling */ - MEM_SET_VTABLE (mio); - } - - return mio; -} - -/** - * mio_file_get_fp: - * @mio: A #MIO object - * - * Gets the underlying #FILE object associated with a #MIO file stream. - * - * <warning><para>The returned object may become invalid after a call to - * mio_free() if the stream was configured to close the file when - * destroyed.</para></warning> - * - * Returns: The underlying #FILE object of the given stream, or %NULL if the - * stream is not a file stream. - */ -FILE * -mio_file_get_fp (MIO *mio) -{ - FILE *fp = NULL; - - if (mio->type == MIO_TYPE_FILE) { - fp = mio->impl.file.fp; - } - - return fp; -} - -/** - * mio_memory_get_data: - * @mio: A #MIO object - * @size: (allow-none) (out): Return location for the length of the returned - * memory, or %NULL - * - * Gets the underlying memory buffer associated with a #MIO memory stream. - * - * <warning><para>The returned pointer and size may become invalid after a - * successful write on the stream or after a call to mio_free() if the stream - * was configured to free the memory when destroyed.</para></warning> - * - * Returns: The memory buffer of the given #MIO stream, or %NULL if the stream - * is not a memory stream. - */ -guchar * -mio_memory_get_data (MIO *mio, - gsize *size) -{ - guchar *ptr = NULL; - - if (mio->type == MIO_TYPE_MEMORY) { - ptr = mio->impl.mem.buf; - if (size) *size = mio->impl.mem.size; - } - - return ptr; -} - -/** - * mio_free: - * @mio: A #MIO object - * - * Destroys a #MIO object. - */ -void -mio_free (MIO *mio) -{ - if (mio) { - mio->v_free (mio); - g_slice_free1 (sizeof *mio, mio); - } -} - -/** - * mio_read: - * @mio: A #MIO object - * @ptr: Pointer to the memory to fill with the read data - * @size: Size of each block to read - * @nmemb: Number o blocks to read - * - * Reads raw data from a #MIO stream. This function behave the same as fread(). - * - * Returns: The number of actually read blocks. If an error occurs or if the - * end of the stream is reached, the return value may be smaller than - * the requested block count, or even 0. This function doesn't - * distinguish between end-of-stream and an error, you should then use - * mio_eof() and mio_error() to determine which occurred. - */ -gsize -mio_read (MIO *mio, - void *ptr, - gsize size, - gsize nmemb) -{ - return mio->v_read (mio, ptr, size, nmemb); -} - -/** - * mio_write: - * @mio: A #MIO object - * @ptr: Pointer to the memory to write on the stream - * @size: Size of each block to write - * @nmemb: Number of block to write - * - * Writes raw data to a #MIO stream. This function behaves the same as fwrite(). - * - * Returns: The number of blocks actually written to the stream. This might be - * smaller than the requested count if a write error occurs. - */ -gsize -mio_write (MIO *mio, - const void *ptr, - gsize size, - gsize nmemb) -{ - return mio->v_write (mio, ptr, size, nmemb); -} - -/** - * mio_putc: - * @mio: A #MIO object - * @c: The character to write - * - * Writes a character to a #MIO stream. This function behaves the same as - * fputc(). - * - * Returns: The written wharacter, or %EOF on error. - */ -gint -mio_putc (MIO *mio, - gint c) -{ - return mio->v_putc (mio, c); -} - -/** - * mio_puts: - * @mio: A #MIO object - * @s: The string to write - * - * Writes a string to a #MIO object. This function behaves the same as fputs(). - * - * Returns: A non-negative integer on success or %EOF on failure. - */ -gint -mio_puts (MIO *mio, - const gchar *s) -{ - return mio->v_puts (mio, s); -} - -/** - * mio_vprintf: - * @mio: A #MIO object - * @format: A printf fomrat string - * @ap: The variadic argument list for the format - * - * Writes a formatted string into a #MIO stream. This function behaves the same - * as vfprintf(). - * - * Returns: The number of bytes written in the stream, or a negative value on - * failure. - */ -gint -mio_vprintf (MIO *mio, - const gchar *format, - va_list ap) -{ - return mio->v_vprintf (mio, format, ap); -} - -/** - * mio_printf: - * @mio: A #MIO object - * @format: A print format string - * @...: Arguments of the format - * - * Writes a formatted string to a #MIO stream. This function behaves the same as - * fprintf(). - * - * Returns: The number of bytes written to the stream, or a negative value on - * failure. - */ -gint -mio_printf (MIO *mio, - const gchar *format, - ...) -{ - gint rv; - va_list ap; - - va_start (ap, format); - rv = mio->v_vprintf (mio, format, ap); - va_end (ap); - - return rv; -} - -/** - * mio_getc: - * @mio: A #MIO object - * - * Gets the current character from a #MIO stream. This function behaves the same - * as fgetc(). - * - * Returns: The read character as a #gint, or %EOF on error. - */ -gint -mio_getc (MIO *mio) -{ - return mio->v_getc (mio); -} - -/** - * mio_ungetc: - * @mio: A #MIO object - * @ch: Character to put back in the stream - * - * Puts a character back in a #MIO stream. This function behaves the sames as - * ungetc(). - * - * <warning><para>It is only guaranteed that one character can be but back at a - * time, even if the implementation may allow more.</para></warning> - * <warning><para>Using this function while the stream cursor is at offset 0 is - * not guaranteed to function properly. As the C99 standard says, it is "an - * obsolescent feature".</para></warning> - * - * Returns: The character put back, or %EOF on error. - */ -gint -mio_ungetc (MIO *mio, - gint ch) -{ - return mio->v_ungetc (mio, ch); -} - -/** - * mio_gets: - * @mio: A #MIO object - * @s: A string to fill with the read data - * @size: The maximum number of bytes to read - * - * Reads a string from a #MIO stream, stopping after the first new-line - * character or at the end of the stream. This function behaves the same as - * fgets(). - * - * Returns: @s on success, %NULL otherwise. - */ -gchar * -mio_gets (MIO *mio, - gchar *s, - gsize size) -{ - return mio->v_gets (mio, s, size); -} - -/** - * mio_clearerr: - * @mio: A #MIO object - * - * Clears the error and end-of-stream indicators of a #MIO stream. This function - * behaves the same as clearerr(). - */ -void -mio_clearerr (MIO *mio) -{ - mio->v_clearerr (mio); -} - -/** - * mio_eof: - * @mio: A #MIO object - * - * Checks whether the end-of-stream indicator of a #MIO stream is set. This - * function behaves the same as feof(). - * - * Returns: A non-null value if the stream reached its end, 0 otherwise. - */ -gint -mio_eof (MIO *mio) -{ - return mio->v_eof (mio); -} - -/** - * mio_error: - * @mio: A #MIO object - * - * Checks whether the error indicator of a #MIO stream is set. This function - * behaves the same as ferror(). - * - * Returns: A non-null value if the stream have an error set, 0 otherwise. - */ -gint -mio_error (MIO *mio) -{ - return mio->v_error (mio); -} - -/** - * mio_seek: - * @mio: A #MIO object - * @offset: Offset of the new place, from @whence - * @whence: Move origin. SEEK_SET moves relative to the start of the stream, - * SEEK_CUR from the current position and SEEK_SET from the end of the - * stream. - * - * Sets the curosr position on a #MIO stream. This functions behaves the same as - * fseek(). See also mio_tell() and mio_setpos(). - * - * Returns: 0 on success, -1 otherwise, in which case errno should be set to - * indicate the error. - */ -gint -mio_seek (MIO *mio, - glong offset, - gint whence) -{ - return mio->v_seek (mio, offset, whence); -} - -/** - * mio_tell: - * @mio: A #MIO object - * - * Gets the current cursor position of a #MIO stream. This function behaves the - * same as ftell(). - * - * Returns: The current offset from the start of the stream, or -1 or error, in - * which case errno is set to indicate the error. - */ -glong -mio_tell (MIO *mio) -{ - return mio->v_tell (mio); -} - -/** - * mio_rewind: - * @mio: A #MIO object - * - * Resets the cursor position to 0, and also the end-of-stream and the error - * indicators of a #MIO stream. - * See also mio_seek() and mio_clearerr(). - */ -void -mio_rewind (MIO *mio) -{ - mio->v_rewind (mio); -} - -/** - * mio_getpos: - * @mio: A #MIO stream - * @pos: (out): A #MIOPos object to fill-in - * - * Stores the current position (and maybe other informations about the stream - * state) of a #MIO stream in order to restore it later with mio_setpos(). This - * function behaves the same as fgetpos(). - * - * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate - * the error. - */ -gint -mio_getpos (MIO *mio, - MIOPos *pos) -{ - gint rv = -1; - - pos->type = mio->type; - rv = mio->v_getpos (mio, pos); - #ifdef MIO_DEBUG - if (rv != -1) { - pos->tag = mio; - } - #endif /* MIO_DEBUG */ - - return rv; -} - -/** - * mio_setpos: - * @mio: A #MIO object - * @pos: (in): A #MIOPos object filled-in by a previous call of mio_getpos() on - * the same stream - * - * Restores the position and state indicators of a #MIO stream previously saved - * by mio_getpos(). - * - * <warning><para>The #MIOPos object must have been initialized by a previous - * call to mio_getpos() on the same stream.</para></warning> - * - * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate - * the error. - */ -gint -mio_setpos (MIO *mio, - MIOPos *pos) -{ - gint rv = -1; - - #ifdef MIO_DEBUG - if (pos->tag != mio) { - g_critical ("mio_setpos((MIO*)%p, (MIOPos*)%p): " - "Given MIOPos was not set by a previous call to mio_getpos() " - "on the same MIO object, which means there is a bug in " - "someone's code.", - (void *)mio, (void *)pos); - errno = EINVAL; - return -1; - } - #endif /* MIO_DEBUG */ - rv = mio->v_setpos (mio, pos); - - return rv; -}
Modified: ctags/mio/mio.h 221 lines changed, 0 insertions(+), 221 deletions(-) =================================================================== @@ -1,221 +0,0 @@ -/* - * MIO, an I/O abstraction layer replicating C file I/O API. - * Copyright (C) 2010 Colomban Wendling ban@herbesfolles.org - * - * This program 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 of the License, or - * (at your option) any later version. - * - * This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef H_MIO_H -#define H_MIO_H - -#include <glib.h> -#include <stdio.h> -#include <stdarg.h> - - -/** - * MIOType: - * @MIO_TYPE_FILE: #MIO object works on a file - * @MIO_TYPE_MEMORY: #MIO object works in-memory - * - * Existing implementations. - */ -enum _MIOType { - MIO_TYPE_FILE, - MIO_TYPE_MEMORY -}; - -typedef enum _MIOType MIOType; -typedef struct _MIO MIO; -typedef struct _MIOPos MIOPos; -/** - * MIOReallocFunc: - * @ptr: Pointer to the memory to resize - * @size: New size of the memory pointed by @ptr - * - * A function following the realloc() semantic. - * - * Returns: A pointer to the start of the new memory, or %NULL on failure. - */ -/* should be GReallocFunc but it's only defined by GIO */ -typedef gpointer (* MIOReallocFunc) (gpointer ptr, - gsize size); - -/** - * MIOFOpenFunc: - * @filename: The filename to open - * @mode: fopen() modes for opening @filename - * - * A function following the fclose() semantic, used to close a #FILE - * object. - * - * Returns: A new #FILE object, or %NULL on failure - */ -typedef FILE *(* MIOFOpenFunc) (const gchar *filename, - const gchar *mode); - -/** - * MIOFCloseFunc: - * @fp: An opened #FILE object - * - * A function following the fclose() semantic, used to close a #FILE - * object. - * - * Returns: 0 on success, EOF otherwise. - */ -typedef gint (* MIOFCloseFunc) (FILE *fp); - -/** - * MIOPos: - * - * An object representing the state of a #MIO stream. This object can be - * statically allocated but all its fields are private and should not be - * accessed directly. - */ -struct _MIOPos { - /*< private >*/ - guint type; -#ifdef MIO_DEBUG - void *tag; -#endif - union { - fpos_t file; - gsize mem; - } impl; -}; - -/** - * MIO: - * - * An object representing a #MIO stream. No assumptions should be made about - * what compose this object, and none of its fields should be accessed directly. - */ -struct _MIO { - /*< private >*/ - guint type; - union { - struct { - FILE *fp; - MIOFCloseFunc close_func; - } file; - struct { - guchar *buf; - gint ungetch; - gsize pos; - gsize size; - gsize allocated_size; - MIOReallocFunc realloc_func; - GDestroyNotify free_func; - gboolean error; - gboolean eof; - } mem; - } impl; - /* virtual function table */ - void (*v_free) (MIO *mio); - gsize (*v_read) (MIO *mio, - void *ptr, - gsize size, - gsize nmemb); - gsize (*v_write) (MIO *mio, - const void *ptr, - gsize size, - gsize nmemb); - gint (*v_getc) (MIO *mio); - gchar *(*v_gets) (MIO *mio, - gchar *s, - gsize size); - gint (*v_ungetc) (MIO *mio, - gint ch); - gint (*v_putc) (MIO *mio, - gint c); - gint (*v_puts) (MIO *mio, - const gchar *s); - gint (*v_vprintf) (MIO *mio, - const gchar *format, - va_list ap) G_GNUC_PRINTF (2, 0); - void (*v_clearerr) (MIO *mio); - gint (*v_eof) (MIO *mio); - gint (*v_error) (MIO *mio); - gint (*v_seek) (MIO *mio, - glong offset, - gint whence); - glong (*v_tell) (MIO *mio); - void (*v_rewind) (MIO *mio); - gint (*v_getpos) (MIO *mio, - MIOPos *pos); - gint (*v_setpos) (MIO *mio, - MIOPos *pos); -}; - - -MIO *mio_new_file (const gchar *filename, - const gchar *mode); -MIO *mio_new_file_full (const gchar *filename, - const gchar *mode, - MIOFOpenFunc open_func, - MIOFCloseFunc close_func); -MIO *mio_new_fp (FILE *fp, - MIOFCloseFunc close_func); -MIO *mio_new_memory (guchar *data, - gsize size, - MIOReallocFunc realloc_func, - GDestroyNotify free_func); -void mio_free (MIO *mio); -FILE *mio_file_get_fp (MIO *mio); -guchar *mio_memory_get_data (MIO *mio, - gsize *size); -gsize mio_read (MIO *mio, - void *ptr, - gsize size, - gsize nmemb); -gsize mio_write (MIO *mio, - const void *ptr, - gsize size, - gsize nmemb); -gint mio_getc (MIO *mio); -gchar *mio_gets (MIO *mio, - gchar *s, - gsize size); -gint mio_ungetc (MIO *mio, - gint ch); -gint mio_putc (MIO *mio, - gint c); -gint mio_puts (MIO *mio, - const gchar *s); - -gint mio_vprintf (MIO *mio, - const gchar *format, - va_list ap) G_GNUC_PRINTF (2, 0); -gint mio_printf (MIO *mio, - const gchar *format, - ...) G_GNUC_PRINTF (2, 3); - -void mio_clearerr (MIO *mio); -gint mio_eof (MIO *mio); -gint mio_error (MIO *mio); -gint mio_seek (MIO *mio, - glong offset, - gint whence); -glong mio_tell (MIO *mio); -void mio_rewind (MIO *mio); -gint mio_getpos (MIO *mio, - MIOPos *pos); -gint mio_setpos (MIO *mio, - MIOPos *pos); - - - -#endif /* guard */
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).