aboutsummaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2003-03-31 02:12:46 +0000
committerdrh <drh@noemail.net>2003-03-31 02:12:46 +0000
commitda93d238c2067a1951b8043c3c30355947fd6da9 (patch)
tree29057f4a84763deb95565d3e8bd2622614c85c15 /src/util.c
parent1c2d84148a6bb2f8d231debd65bc09e948abf029 (diff)
downloadsqlite-da93d238c2067a1951b8043c3c30355947fd6da9.tar.gz
sqlite-da93d238c2067a1951b8043c3c30355947fd6da9.zip
Add the sqliteErrorMsg() function and use it to generate error message
text during parsing and code generation. This simplifies the code somewhat and makes it easier to handle names with a database prefix. (CVS 891) FossilOrigin-Name: 1d3fc977211abdc7ba3fd51d661863e8ce5aef69
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c130
1 files changed, 129 insertions, 1 deletions
diff --git a/src/util.c b/src/util.c
index 8231e9818..87e5f4431 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.58 2003/02/16 22:21:32 drh Exp $
+** $Id: util.c,v 1.59 2003/03/31 02:12:48 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -393,6 +393,134 @@ void sqliteSetNString(char **pz, ...){
}
/*
+** Add an error message to pParse->zErrMsg and increment pParse->nErr.
+** The following formatting characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+*/
+void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
+ va_list ap;
+ int nByte;
+ int i, j;
+ char *z;
+ static char zNull[] = "NULL";
+
+ pParse->nErr++;
+ nByte = 1 + strlen(zFormat);
+ va_start(ap, zFormat);
+ for(i=0; zFormat[i]; i++){
+ if( zFormat[i]!='%' && zFormat[i+1] ) continue;
+ i++;
+ switch( zFormat[i] ){
+ case 'd': {
+ (void)va_arg(ap, int);
+ nByte += 20;
+ break;
+ }
+ case 'z':
+ case 's': {
+ char *z2 = va_arg(ap, char*);
+ if( z2==0 ) z2 = zNull;
+ nByte += strlen(z2);
+ break;
+ }
+ case 'T': {
+ Token *p = va_arg(ap, Token*);
+ nByte += p->n;
+ break;
+ }
+ case 'S': {
+ SrcList *p = va_arg(ap, SrcList*);
+ int k = va_arg(ap, int);
+ assert( p->nSrc>k && k>=0 );
+ nByte += strlen(p->a[k].zName);
+ if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
+ nByte += strlen(p->a[k].zDatabase)+1;
+ }
+ break;
+ }
+ default: {
+ nByte++;
+ break;
+ }
+ }
+ }
+ va_end(ap);
+ z = sqliteMalloc( nByte );
+ if( z==0 ) return;
+ sqliteFree(pParse->zErrMsg);
+ pParse->zErrMsg = z;
+ va_start(ap, zFormat);
+ for(i=j=0; zFormat[i]; i++){
+ if( zFormat[i]!='%' ) continue;
+ if( i>j ){
+ memcpy(z, &zFormat[j], i-j);
+ z += i-j;
+ }
+ j = i+2;
+ i++;
+ switch( zFormat[i] ){
+ case 'd': {
+ int x = va_arg(ap, int);
+ sprintf(z, "%d", x);
+ z += strlen(z);
+ break;
+ }
+ case 'z':
+ case 's': {
+ int len;
+ char *z2 = va_arg(ap, char*);
+ if( z2==0 ) z2 = zNull;
+ len = strlen(z2);
+ memcpy(z, z2, len);
+ z += len;
+ if( zFormat[i]=='z' && z2!=zNull ){
+ sqliteFree(z2);
+ }
+ break;
+ }
+ case 'T': {
+ Token *p = va_arg(ap, Token*);
+ memcpy(z, p->z, p->n);
+ z += p->n;
+ break;
+ }
+ case 'S': {
+ int len;
+ SrcList *p = va_arg(ap, SrcList*);
+ int k = va_arg(ap, int);
+ assert( p->nSrc>k && k>=0 );
+ if( p->a[k].zDatabase && p->a[k].zDatabase[0] ){
+ len = strlen(p->a[k].zDatabase);
+ memcpy(z, p->a[k].zDatabase, len);
+ z += len;
+ *(z++) = '.';
+ }
+ len = strlen(p->a[k].zName);
+ memcpy(z, p->a[k].zName, len);
+ z += len;
+ break;
+ }
+ default: {
+ *(z++) = zFormat[i];
+ break;
+ }
+ }
+ }
+ va_end(ap);
+ if( i>j ){
+ memcpy(z, &zFormat[j], i-j);
+ z += i-j;
+ }
+ assert( (z - pParse->zErrMsg) < nByte );
+ *z = 0;
+}
+
+/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters. The conversion is done in-place. If the
** input does not begin with a quote character, then this routine