debuggers: import openocd-0.7.0
Initial check-in of openocd-0.7.0 as it can be downloaded from http://sourceforge.net/projects/openocd/files/openocd/0.7.0/ Any modifications will follow. Change-Id: I6949beaefd589e046395ea0cb80f4e1ab1654d55
This commit is contained in:
300
debuggers/openocd/jimtcl/jim-sqlite3.c
Normal file
300
debuggers/openocd/jimtcl/jim-sqlite3.c
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Jim - Sqlite bindings
|
||||
*
|
||||
* Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* official policies, either expressed or implied, of the Jim Tcl Project.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <jim.h>
|
||||
|
||||
typedef struct JimSqliteHandle
|
||||
{
|
||||
sqlite3 *db;
|
||||
} JimSqliteHandle;
|
||||
|
||||
static void JimSqliteDelProc(Jim_Interp *interp, void *privData)
|
||||
{
|
||||
JimSqliteHandle *sh = privData;
|
||||
|
||||
JIM_NOTUSED(interp);
|
||||
|
||||
sqlite3_close(sh->db);
|
||||
Jim_Free(sh);
|
||||
}
|
||||
|
||||
static char *JimSqliteQuoteString(const char *str, int len, int *newLenPtr)
|
||||
{
|
||||
int i, newLen, c = 0;
|
||||
const char *s;
|
||||
char *d, *buf;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (str[i] == '\'')
|
||||
c++;
|
||||
newLen = len + c;
|
||||
s = str;
|
||||
d = buf = Jim_Alloc(newLen);
|
||||
while (len--) {
|
||||
if (*s == '\'')
|
||||
*d++ = '\'';
|
||||
*d++ = *s++;
|
||||
}
|
||||
*newLenPtr = newLen;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static Jim_Obj *JimSqliteFormatQuery(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
|
||||
int objc, Jim_Obj *const *objv)
|
||||
{
|
||||
const char *fmt;
|
||||
int fmtLen;
|
||||
Jim_Obj *resObjPtr;
|
||||
|
||||
fmt = Jim_GetString(fmtObjPtr, &fmtLen);
|
||||
resObjPtr = Jim_NewStringObj(interp, "", 0);
|
||||
while (fmtLen) {
|
||||
const char *p = fmt;
|
||||
char spec[2];
|
||||
|
||||
while (*fmt != '%' && fmtLen) {
|
||||
fmt++;
|
||||
fmtLen--;
|
||||
}
|
||||
Jim_AppendString(interp, resObjPtr, p, fmt - p);
|
||||
if (fmtLen == 0)
|
||||
break;
|
||||
fmt++;
|
||||
fmtLen--; /* skip '%' */
|
||||
if (*fmt != '%') {
|
||||
if (objc == 0) {
|
||||
Jim_FreeNewObj(interp, resObjPtr);
|
||||
Jim_SetResultString(interp, "not enough arguments for all format specifiers", -1);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
objc--;
|
||||
}
|
||||
}
|
||||
switch (*fmt) {
|
||||
case 's':
|
||||
{
|
||||
const char *str;
|
||||
char *quoted;
|
||||
int len, newLen;
|
||||
|
||||
str = Jim_GetString(objv[0], &len);
|
||||
quoted = JimSqliteQuoteString(str, len, &newLen);
|
||||
Jim_AppendString(interp, resObjPtr, quoted, newLen);
|
||||
Jim_Free(quoted);
|
||||
}
|
||||
objv++;
|
||||
break;
|
||||
case '%':
|
||||
Jim_AppendString(interp, resObjPtr, "%", 1);
|
||||
break;
|
||||
default:
|
||||
spec[0] = *fmt;
|
||||
spec[1] = '\0';
|
||||
Jim_FreeNewObj(interp, resObjPtr);
|
||||
Jim_SetResultFormatted(interp,
|
||||
"bad field specifier \"%s\", only %%s and %%%% are valid", spec);
|
||||
return NULL;
|
||||
}
|
||||
fmt++;
|
||||
fmtLen--;
|
||||
}
|
||||
return resObjPtr;
|
||||
}
|
||||
|
||||
/* Calls to [sqlite.open] create commands that are implemented by this
|
||||
* C command. */
|
||||
static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
JimSqliteHandle *sh = Jim_CmdPrivData(interp);
|
||||
int option;
|
||||
static const char * const options[] = {
|
||||
"close", "query", "lastid", "changes", NULL
|
||||
};
|
||||
enum
|
||||
{ OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES };
|
||||
|
||||
if (argc < 2) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
|
||||
return JIM_ERR;
|
||||
}
|
||||
if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite method", JIM_ERRMSG) != JIM_OK)
|
||||
return JIM_ERR;
|
||||
/* CLOSE */
|
||||
if (option == OPT_CLOSE) {
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 2, argv, "");
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_DeleteCommand(interp, Jim_String(argv[0]));
|
||||
return JIM_OK;
|
||||
}
|
||||
else if (option == OPT_QUERY) {
|
||||
/* QUERY */
|
||||
Jim_Obj *objPtr, *rowsListPtr;
|
||||
sqlite3_stmt *stmt;
|
||||
const char *query, *tail;
|
||||
int columns, rows, len;
|
||||
char *nullstr;
|
||||
|
||||
if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) {
|
||||
nullstr = Jim_StrDup(Jim_String(argv[3]));
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
else {
|
||||
nullstr = Jim_StrDup("");
|
||||
}
|
||||
if (argc < 3) {
|
||||
Jim_WrongNumArgs(interp, 2, argv, "query ?args?");
|
||||
Jim_Free(nullstr);
|
||||
return JIM_ERR;
|
||||
}
|
||||
objPtr = JimSqliteFormatQuery(interp, argv[2], argc - 3, argv + 3);
|
||||
if (objPtr == NULL) {
|
||||
Jim_Free(nullstr);
|
||||
return JIM_ERR;
|
||||
}
|
||||
query = Jim_GetString(objPtr, &len);
|
||||
Jim_IncrRefCount(objPtr);
|
||||
/* Compile the query into VM code */
|
||||
if (sqlite3_prepare_v2(sh->db, query, len, &stmt, &tail) != SQLITE_OK) {
|
||||
Jim_DecrRefCount(interp, objPtr);
|
||||
Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1);
|
||||
Jim_Free(nullstr);
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_DecrRefCount(interp, objPtr); /* query no longer needed. */
|
||||
/* Build a list of rows (that are lists in turn) */
|
||||
rowsListPtr = Jim_NewListObj(interp, NULL, 0);
|
||||
Jim_IncrRefCount(rowsListPtr);
|
||||
rows = 0;
|
||||
columns = sqlite3_column_count(stmt);
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
int i;
|
||||
|
||||
objPtr = Jim_NewListObj(interp, NULL, 0);
|
||||
for (i = 0; i < columns; i++) {
|
||||
Jim_Obj *vObj = NULL;
|
||||
|
||||
Jim_ListAppendElement(interp, objPtr,
|
||||
Jim_NewStringObj(interp, sqlite3_column_name(stmt, i), -1));
|
||||
switch (sqlite3_column_type(stmt, i)) {
|
||||
case SQLITE_NULL:
|
||||
vObj = Jim_NewStringObj(interp, nullstr, -1);
|
||||
break;
|
||||
case SQLITE_INTEGER:
|
||||
vObj = Jim_NewIntObj(interp, sqlite3_column_int(stmt, i));
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
vObj = Jim_NewDoubleObj(interp, sqlite3_column_double(stmt, i));
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
case SQLITE_BLOB:
|
||||
vObj = Jim_NewStringObj(interp,
|
||||
sqlite3_column_blob(stmt, i), sqlite3_column_bytes(stmt, i));
|
||||
break;
|
||||
}
|
||||
Jim_ListAppendElement(interp, objPtr, vObj);
|
||||
}
|
||||
Jim_ListAppendElement(interp, rowsListPtr, objPtr);
|
||||
rows++;
|
||||
}
|
||||
/* Finalize */
|
||||
Jim_Free(nullstr);
|
||||
if (sqlite3_finalize(stmt) != SQLITE_OK) {
|
||||
Jim_DecrRefCount(interp, rowsListPtr);
|
||||
Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_SetResult(interp, rowsListPtr);
|
||||
Jim_DecrRefCount(interp, rowsListPtr);
|
||||
}
|
||||
else if (option == OPT_LASTID) {
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 2, argv, "");
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_last_insert_rowid(sh->db)));
|
||||
return JIM_OK;
|
||||
}
|
||||
else if (option == OPT_CHANGES) {
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 2, argv, "");
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_SetResult(interp, Jim_NewIntObj(interp, sqlite3_changes(sh->db)));
|
||||
return JIM_OK;
|
||||
}
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
sqlite3 *db;
|
||||
JimSqliteHandle *sh;
|
||||
char buf[60];
|
||||
int r;
|
||||
|
||||
if (argc != 2) {
|
||||
Jim_WrongNumArgs(interp, 1, argv, "dbname");
|
||||
return JIM_ERR;
|
||||
}
|
||||
r = sqlite3_open(Jim_String(argv[1]), &db);
|
||||
if (r != SQLITE_OK) {
|
||||
Jim_SetResultString(interp, sqlite3_errmsg(db), -1);
|
||||
sqlite3_close(db);
|
||||
return JIM_ERR;
|
||||
}
|
||||
/* Create the file command */
|
||||
sh = Jim_Alloc(sizeof(*sh));
|
||||
sh->db = db;
|
||||
snprintf(buf, sizeof(buf), "sqlite.handle%ld", Jim_GetId(interp));
|
||||
Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, sh, JimSqliteDelProc);
|
||||
Jim_SetResultString(interp, buf, -1);
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
int Jim_sqlite3Init(Jim_Interp *interp)
|
||||
{
|
||||
if (Jim_PackageProvide(interp, "sqlite3", "1.0", JIM_ERRMSG))
|
||||
return JIM_ERR;
|
||||
|
||||
Jim_CreateCommand(interp, "sqlite3.open", JimSqliteOpenCommand, NULL, NULL);
|
||||
return JIM_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user