/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
#if !defined(NET_FOSSIL_SCM_FSL_INTERNAL_H_INCLUDED)
#define NET_FOSSIL_SCM_FSL_INTERNAL_H_INCLUDED
/*
** Copyright (c) 2013 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** 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.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
** This file declares library-level internal APIs which are shared
** across the library.
*/
#include <stdio.h> /* FILE type */
#include <sqlite3.h> /* include this here, instead of each impl file,
to simplify porting if we move to v4 */
#include "fossil/fossil2.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*
** The main Fossil "context" type. This is the first argument to
** most Fossil v2 API routines.
**
** This type will likely eventually be made opaque to client code -
** do not depend on any of its members/contents. Having it
** non-opaque also has advantages, though. We'll see. Binary
** compatibility concerns might force us to make it opaque. But for
** now having it public simplifies testing and debugging.
**
** An instance's lifetime looks like:
**
** @code
** int rc;
** fsl_ctx * f = NULL;
** rc = fsl_init( &f, NULL );
** assert(!rc);
** rc = fsl_repo_open_db( f, "myrepo.fsl" );
** ...
** fsl_finalize(f);
** @endcode
*/
struct fsl_ctx {
/*
** Current repository db.
*/
fsl_db dbRepo;
/*
** Output channel used by fsl_output() and friends.
*/
fsl_outputer output;
/*
** Can be used to tie client-specific data to the context. Its
** finalizer is called when fsl_finalize() cleans up.
*/
fsl_state clientState;
/*
** Holds error state. As a general rule, this information is
** updated only by routines which need to return more info than a
** simple integer error string. This is primarily db-related
** routines, where we add the db-driver-provided error state
** here. It is not used by "simple" routines for which an integer
** code always suffices. APIs which set this should denote it
** with a comment like "sets the context's error state on error."
*/
fsl_error error;
/*
** Optimization: reusable scratchpad for creating strings.
*/
fsl_buffer scratch;
/*
** Not yet used. Needed?
**
** The directory part of an opened repository db.
*/
fsl_buffer repoDir;
struct {
char traceSql;
char printSql;
} debug;
/* no state related to server/user/etc. That is higher-level stuff. */
};
/** Initialized-with-defaults fsl_ctx instance. */
#define fsl_ctx_empty_m { fsl_db_empty_m /*dbRepo*/, \
fsl_outputer_FILE_m /*output*/, \
fsl_state_empty_m /*clientState*/, \
fsl_error_empty_m /*error*/, \
fsl_buffer_empty_m /*scratch*/, \
fsl_buffer_empty_m /*repoDir*/, \
{/*debug*/ \
0/*traceSql*/, \
0/*printSql*/ \
} \
}
/** Initialized-with-defaults fsl_ctx instance. */
extern const fsl_ctx fsl_ctx_empty;
/*
** Quivalent to fopen(3) but expects name to be UTF8-encoded.
*/
FILE * fsl_fopen(char const * name, char const *mode);
/*
** Closes the given db handle. Returns 0 on success. Note that db itself
** is not freed - it is assumed to either be on the stack or part of
** a larger struct.
*/
int fsl_db_close( fsl_db * db );
/*
** Opens the given db file and populates db with its handle.
** db must have been cleanly initialized by copy-constructing it from
** fsl_db_empty. Failure to do so will lead to undefined behaviour.
**
** Returns FSL_RC_MISUSE if !db, !repoDbFile, !*repoDbFile, or
** if db->dbh is not NULL.
**
** ACHTUNG: it is up to the caller to set db->f. That is currently
** used by some error reporting code.
**
** On error db->dbh will not be set, but db->dbh.error might contain
** error details. Regardless of success or failure, db should be
** passed to fsl_db_close() to free up all memory associated with it.
**
** openFlags is not yet used. Just pass 0.
*/
int fsl_db_open( fsl_db * db, char const * repoDbFile, int openFlags );
#ifdef _WIN32
/*
** Translate MBCS to UTF-8. Return a pointer to the translated
** text. ACHTUNG: Call fsl_mbcs_free() (not fsl_free()) to
** deallocate any memory used to store the returned pointer when
** done.
*/
char * fsl_mbcs_to_utf8(char const * mbcs);
/*
** Frees a string allocated from fsl_mbcs_to_utf8(). Results are undefined
** if mbcs was allocated using any other mechanism.
*/
void fsl_mbcs_free(char * mbcs);
#endif
/* _WIN32 */
/*
** Translate Unicode text into UTF-8.
** Return a pointer to the translated text.
** Call fsl_unicode_free() to deallocate any memory used to store the
** returned pointer when done.
**
** This function exists only for Windows. On other platforms it
** behaves like fsl_strdup().
*/
char *fsl_unicode_to_utf8(const void *zUnicode);
/*
** Translate UTF-8 to unicode for use in system calls. Return a
** pointer to the translated text. The returned value must
** eventually be passed to fsl_free() to deallocate any memory used
** to store the returned pointer when done.
**
** This function exists only for Windows. On other platforms
** it behaves like fsl_strdup().
**
*/
void *fsl_utf8_to_unicode(const char *zUtf8);
/*
** Translate text from the filename character set into UTF-8.
** Return a pointer to the translated text. Call
** fsl_filename_free() to deallocate any memory used to store the
** returned pointer when done.
**
** This function must not convert '\' to '/' on windows/cygwin, as it is
** used in places where we are not sure it's really filenames we are handling,
** e.g. fsl_getenv() or handling the argv arguments from main().
**
** On Windows, translate some characters in the in the range
** U+F001 - U+F07F (private use area) to ASCII. Cygwin sometimes
** generates such filenames. See:
** <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
*/
char *fsl_filename_to_utf8(const void *zFilename);
/*
** Translate text from UTF-8 to the filename character set.
** Return a pointer to the translated text.
** Call fossil_filename_free() to deallocate any memory used to store the
** returned pointer when done.
**
** On Windows, characters in the range U+0001 to U+0031 and the
** characters '"', '*', ':', '<', '>', '?' and '|' are invalid
** to be used. Therefore, translate those to characters in the
** in the range U+F001 - U+F07F (private use area), so those
** characters never arrive in any Windows API. The filenames might
** look strange in Windows explorer, but in the cygwin shell
** everything looks as expected.
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fsl_utf8_to_filename(const char *zUtf8);
/*
** Deallocate pOld, which must have been allocated by
** fsl_filename_to_utf8() or fsl_utf8_to_filename().
*/
void fsl_filename_free(void *pOld);
/*
** Returns true (non-0) if ch is-a alpha character.
*/
char fsl_isalpha(int ch);
#if defined(__cplusplus)
} /*extern "C"*/
#endif
#endif
/* NET_FOSSIL_SCM_FSL_INTERNAL_H_INCLUDED */