<commit_before>/*
 * libdbi - database independent abstraction layer for C.
 * Copyright (C) 2001-2002, <NAME> and <NAME>.
 * http://libdbi.sourceforge.net
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 * $Id: dbi_main.c,v 1.34 2002/06/19 01:23:33 dap Exp $
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE /* since we need the asprintf() prototype */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include <math.h>
#include <limits.h>

#include <dbi/dbi.h>
#include <dbi/dbi-dev.h>

#ifndef DBI_DRIVER_DIR
#define DBI_DRIVER_DIR "/usr/local/lib/dbd" /* use this as the default */
#endif

/* declarations for internal functions -- anything declared as static won't be accessible by name from client programs */
static dbi_driver_t *_get_driver(const char *filename);
static void _free_custom_functions(dbi_driver_t *driver);
static dbi_option_t *_find_or_create_option_node(dbi_conn Conn, const char *key);
static int _update_internal_conn_list(dbi_conn_t *conn, int operation);
static void _free_caps(_capability_t *caproot);
static const char *_get_option(dbi_conn Conn, const char *key, int aggressive);
static int _get_option_numeric(dbi_conn Conn, const char *key, int aggressive);

void _error_handler(dbi_conn_t *conn, dbi_error_flag errflag);
extern int _disjoin_from_conn(dbi_result_t *result);

dbi_result dbi_conn_query(dbi_conn Conn, const char *formatstr, ...) __attribute__ ((format (printf, 2, 3)));
int dbi_conn_set_error(dbi_conn Conn, int errnum, const char *formatstr, ...) __attribute__ ((format (printf, 3, 4)));

static const char *ERROR = "ERROR";
static dbi_driver_t *rootdriver;
static dbi_conn_t *rootconn;

/* XXX DBI CORE FUNCTIONS XXX */

int dbi_initialize(const char *driverdir) {
	DIR *dir;
	struct dirent *driver_dirent = NULL;
	struct stat statbuf;
	char fullpath[FILENAME_MAX];
	char *effective_driverdir;
	
	int num_loaded = 0;
	dbi_driver_t *driver = NULL;
	dbi_driver_t *prevdriver = NULL;
	
	rootdriver = NULL;
	effective_driverdir = (driverdir ? (char *)driverdir : DBI_DRIVER_DIR);
	dir = opendir(effective_driverdir);

	if (dir == NULL) {
		return -1;
	}
	else {
		while ((driver_dirent = readdir(dir)) != NULL) {
			driver = NULL;
			snprintf(fullpath, FILENAME_MAX, "%s/%s", effective_driverdir, driver_dirent->d_name);
			if ((stat(fullpath, &statbuf) == 0) && S_ISREG(statbuf.st_mode) && (!strcmp(strrchr(driver_dirent->d_name, '.'), DRIVER_EXT))) {
				/* file is a stat'able regular file that ends in .so (or appropriate dynamic library extension) */
				driver = _get_driver(fullpath);
				if (driver && (driver->functions->initialize(driver) != -1)) {
					if (!rootdriver) {
						rootdriver = driver;
					}
					if (prevdriver) {
						prevdriver->next = driver;
					}
					prevdriver = driver;
					num_loaded++;
				}
				else {
					if (driver && driver->dlhandle) dlclose(driver->dlhandle);
					if (driver && driver->functions) free(driver->functions);
					if (driver) free(driver);
					driver = NULL; /* don't include in linked list */
				}
			}
		}
		closedir(dir);
	}
	
	return num_loaded;
}

void dbi_shutdown() {
	dbi_conn_t *curconn = rootconn;
	dbi_conn_t *nextconn;
	
	dbi_driver_t *curdriver = rootdriver;
	dbi_driver_t *nextdriver;
	
	while (curconn) {
		nextconn = curconn->next;
		dbi_conn_close((dbi_conn)curconn);
		curconn = nextconn;
	}
	
	while (curdriver) {
		nextdriver = curdriver->next;
		dlclose(curdriver->dlhandle);
		free(curdriver->functions);
		_free_custom_functions(curdriver);
		_free_caps(curdriver->caps);
		free(curdriver->filename);
		free(curdriver);
		curdriver = nextdriver;
	}

	rootdriver = NULL;
}

const char *dbi_version() {
	return "libdbi v" VERSION;
}

/* XXX DRIVER FUNCTIONS XXX */

dbi_driver dbi_driver_list(dbi_driver Current) {
	dbi_driver_t *current = Current;

	if (current == NULL) {
		return (dbi_driver)rootdriver;
	}

	return (dbi_driver)current->next;
}

dbi_driver dbi_driver_open(const char *name) {
	dbi_driver_t *driver = rootdriver;

	while (driver && strcasecmp(name, driver->info->name)) {
		driver = driver->next;
	}

	return driver;
}

int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word) {
	unsigned int idx = 0;
	dbi_driver_t *driver = Driver;
	
	if (!driver) return 0;
	
	while (driver->reserved_words[idx]) {
		if (strcasecmp(word, driver->reserved_words[idx]) == 0) {
			return 1;
		}
	}
	return 0;
}<commit_msg>cms has a brown paper bag waiting for me as soon as this is committed ;)<commit_after>/*
 * libdbi - database independent abstraction layer for C.
 * Copyright (C) 2001-2002, <NAME> and <NAME>.
 * http://libdbi.sourceforge.net
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 * $Id: dbi_main.c,v 1.35 2002/06/19 16:14:11 dap Exp $
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE /* since we need the asprintf() prototype */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include <math.h>
#include <limits.h>

#include <dbi/dbi.h>
#include <dbi/dbi-dev.h>

#ifndef DBI_DRIVER_DIR
#define DBI_DRIVER_DIR "/usr/local/lib/dbd" /* use this as the default */
#endif

/* declarations for internal functions -- anything declared as static won't be accessible by name from client programs */
static dbi_driver_t *_get_driver(const char *filename);
static void _free_custom_functions(dbi_driver_t *driver);
static dbi_option_t *_find_or_create_option_node(dbi_conn Conn, const char *key);
static int _update_internal_conn_list(dbi_conn_t *conn, int operation);
static void _free_caps(_capability_t *caproot);
static const char *_get_option(dbi_conn Conn, const char *key, int aggressive);
static int _get_option_numeric(dbi_conn Conn, const char *key, int aggressive);

void _error_handler(dbi_conn_t *conn, dbi_error_flag errflag);
extern int _disjoin_from_conn(dbi_result_t *result);

dbi_result dbi_conn_query(dbi_conn Conn, const char *formatstr, ...) __attribute__ ((format (printf, 2, 3)));
int dbi_conn_set_error(dbi_conn Conn, int errnum, const char *formatstr, ...) __attribute__ ((format (printf, 3, 4)));

static const char *ERROR = "ERROR";
static dbi_driver_t *rootdriver;
static dbi_conn_t *rootconn;

/* XXX DBI CORE FUNCTIONS XXX */

int dbi_initialize(const char *driverdir) {
	DIR *dir;
	struct dirent *driver_dirent = NULL;
	struct stat statbuf;
	char fullpath[FILENAME_MAX];
	char *effective_driverdir;
	
	int num_loaded = 0;
	dbi_driver_t *driver = NULL;
	dbi_driver_t *prevdriver = NULL;
	
	rootdriver = NULL;
	effective_driverdir = (driverdir ? (char *)driverdir : DBI_DRIVER_DIR);
	dir = opendir(effective_driverdir);

	if (dir == NULL) {
		return -1;
	}
	else {
		while ((driver_dirent = readdir(dir)) != NULL) {
			driver = NULL;
			snprintf(fullpath, FILENAME_MAX, "%s/%s", effective_driverdir, driver_dirent->d_name);
			if ((stat(fullpath, &statbuf) == 0) && S_ISREG(statbuf.st_mode) && (!strcmp(strrchr(driver_dirent->d_name, '.'), DRIVER_EXT))) {
				/* file is a stat'able regular file that ends in .so (or appropriate dynamic library extension) */
				driver = _get_driver(fullpath);
				if (driver && (driver->functions->initialize(driver) != -1)) {
					if (!rootdriver) {
						rootdriver = driver;
					}
					if (prevdriver) {
						prevdriver->next = driver;
					}
					prevdriver = driver;
					num_loaded++;
				}
				else {
					if (driver && driver->dlhandle) dlclose(driver->dlhandle);
					if (driver && driver->functions) free(driver->functions);
					if (driver) free(driver);
					driver = NULL; /* don't include in linked list */
				}
			}
		}
		closedir(dir);
	}
	
	return num_loaded;
}

void dbi_shutdown() {
	dbi_conn_t *curconn = rootconn;
	dbi_conn_t *nextconn;
	
	dbi_driver_t *curdriver = rootdriver;
	dbi_driver_t *nextdriver;
	
	while (curconn) {
		nextconn = curconn->next;
		dbi_conn_close((dbi_conn)curconn);
		curconn = nextconn;
	}
	
	while (curdriver) {
		nextdriver = curdriver->next;
		dlclose(curdriver->dlhandle);
		free(curdriver->functions);
		_free_custom_functions(curdriver);
		_free_caps(curdriver->caps);
		free(curdriver->filename);
		free(curdriver);
		curdriver = nextdriver;
	}

	rootdriver = NULL;
}

const char *dbi_version() {
	return "libdbi v" VERSION;
}

/* XXX DRIVER FUNCTIONS XXX */

dbi_driver dbi_driver_list(dbi_driver Current) {
	dbi_driver_t *current = Current;

	if (current == NULL) {
		return (dbi_driver)rootdriver;
	}

	return (dbi_driver)current->next;
}

dbi_driver dbi_driver_open(const char *name) {
	dbi_driver_t *driver = rootdriver;

	while (driver && strcasecmp(name, driver->info->name)) {
		driver = driver->next;
	}

	return driver;
}

int dbi_driver_is_reserved_word(dbi_driver Driver, const char *word) {
	unsigned int idx = 0;
	dbi_driver_t *driver = Driver;
	
	if (!driver) return 0;
	
	while (driver->reserved_words[idx]) {
		if (strcasecmp(word, driver->reserved_words[idx]) == 0) {
			return 1;
		}
		idx++;
	}
	return 0;
}
{'fraction_non_alphanumeric': 0.11772006874164598, 'fraction_numerical': 0.01031124689707848, 'mean_word_length': 4.374551051821447, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2431816', 'n_tokens_mistral': 3953, 'n_tokens_neox': 3562, 'n_words': 1032}