Get rid of old-style function declarations/definitions in lemon.c

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Get rid of old-style function declarations/definitions in lemon.c

Guy Harris
Here's a patch, against the current Fossil repository, including some changes we've made to lemon.c in Wireshark, that gets rid of old-style K&R function definitions/declarations, and also removes trailing white space from some lines (the Wireshark pre-commit hook complains about them):

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Get rid of old-style function declarations/definitions in lemon.c

Dominique Devienne
On Thu, Apr 13, 2017 at 6:18 AM, Guy Harris <[hidden email]> wrote:

> Here's a patch, against the current Fossil repository, including some
> changes we've made to lemon.c in Wireshark, that gets rid of old-style K&R
> function definitions/declarations, and also removes trailing white space
> from some lines (the Wireshark pre-commit hook complains about them):
>

Attachments are stripped on this list.
Paste the diff/patch as text in your message,
if you want it to be considered. --DD
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Get rid of old-style function declarations/definitions in lemon.c

Guy Harris
On Apr 13, 2017, at 2:36 AM, Dominique Devienne <[hidden email]> wrote:

> On Thu, Apr 13, 2017 at 6:18 AM, Guy Harris <[hidden email]> wrote:
>
>> Here's a patch, against the current Fossil repository, including some
>> changes we've made to lemon.c in Wireshark, that gets rid of old-style K&R
>> function definitions/declarations, and also removes trailing white space
>> from some lines (the Wireshark pre-commit hook complains about them):
>
> Attachments are stripped on this list.
> Paste the diff/patch as text in your message,
> if you want it to be considered. --DD

OK:

Index: tool/lemon.c
==================================================================
--- tool/lemon.c
+++ tool/lemon.c
@@ -166,16 +166,16 @@
 
 static struct action *Action_new(void);
 static struct action *Action_sort(struct action *);
 
 /********** From the file "build.h" ************************************/
-void FindRulePrecedences();
-void FindFirstSets();
-void FindStates();
-void FindLinks();
-void FindFollowSets();
-void FindActions();
+void FindRulePrecedences(struct lemon *);
+void FindFirstSets(struct lemon *);
+void FindStates(struct lemon *);
+void FindLinks(struct lemon *);
+void FindFollowSets(struct lemon *);
+void FindActions(struct lemon *);
 
 /********* From the file "configlist.h" *********************************/
 void Configlist_init(void);
 struct config *Configlist_add(struct rule *, int);
 struct config *Configlist_addbasis(struct rule *, int);
@@ -455,11 +455,11 @@
 int Configcmp(const char *, const char *);
 struct state *State_new(void);
 void State_init(void);
 int State_insert(struct state *, struct config *);
 struct state *State_find(struct config *);
-struct state **State_arrayof(/*  */);
+struct state **State_arrayof(void);
 
 /* Routines used for efficiency in Configlist_add */
 
 void Configtable_init(void);
 int Configtable_insert(struct config *);
@@ -559,12 +559,12 @@
 ** of the lookahead input, then the value of the action_number output is
 ** aAction[X].action.  If the lookaheads do not match then the
 ** default action for the state_number is returned.
 **
 ** All actions associated with a single state_number are first entered
-** into aLookahead[] using multiple calls to acttab_action().  Then the
-** actions for that single state_number are placed into the aAction[]
+** into aLookahead[] using multiple calls to acttab_action().  Then the
+** actions for that single state_number are placed into the aAction[]
 ** array with a single call to acttab_insert().  The acttab_insert() call
 ** also resets the aLookahead[] array in preparation for the next
 ** state number.
 */
 struct lookahead_action {
@@ -610,11 +610,11 @@
   }
   memset(p, 0, sizeof(*p));
   return p;
 }
 
-/* Add a new action to the current transaction set.  
+/* Add a new action to the current transaction set.
 **
 ** This routine is called once for each lookahead for a particular
 ** state.
 */
 void acttab_action(acttab *p, int lookahead, int action){
@@ -672,11 +672,11 @@
       p->aAction[i].lookahead = -1;
       p->aAction[i].action = -1;
     }
   }
 
-  /* Scan the existing action table looking for an offset that is a
+  /* Scan the existing action table looking for an offset that is a
   ** duplicate of the current transaction set.  Fall out of the loop
   ** if and when the duplicate is found.
   **
   ** i is the index in p->aAction[] where p->mnLookahead is inserted.
   */
@@ -750,11 +750,11 @@
 ** Routines to construction the finite state machine for the LEMON
 ** parser generator.
 */
 
 /* Find a precedence symbol of every rule in the grammar.
-**
+**
 ** Those rules which have a precedence symbol coded in the input
 ** grammar using the "[symbol]" construct will already have the
 ** rp->precsym field filled.  Other rules take as their precedence
 ** symbol the first RHS symbol with a defined precedence.  If there
 ** are not RHS symbols with a defined precedence, the precedence
@@ -1070,11 +1070,11 @@
   for(i=0; i<lemp->nstate; i++){
     for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
       cfp->status = INCOMPLETE;
     }
   }
-  
+
   do{
     progress = 0;
     for(i=0; i<lemp->nstate; i++){
       for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
         if( cfp->status==COMPLETE ) continue;
@@ -1101,11 +1101,11 @@
   struct config *cfp;
   struct state *stp;
   struct symbol *sp;
   struct rule *rp;
 
-  /* Add all of the reduce actions
+  /* Add all of the reduce actions
   ** A reduce action is added for each element of the followset of
   ** a configuration which has its dot at the extreme right.
   */
   for(i=0; i<lemp->nstate; i++){   /* Loop over all states */
     stp = lemp->sorted[i];
@@ -1218,11 +1218,11 @@
       apy->type = RD_RESOLVED;
     }else if( spx->prec<spy->prec ){
       apx->type = RD_RESOLVED;
     }
   }else{
-    assert(
+    assert(
       apx->type==SH_RESOLVED ||
       apx->type==RD_RESOLVED ||
       apx->type==SSCONFLICT ||
       apx->type==SRCONFLICT ||
       apx->type==RRCONFLICT ||
@@ -1249,11 +1249,11 @@
 static struct config **currentend = 0;   /* Last on list of configs */
 static struct config *basis = 0;         /* Top of list of basis configs */
 static struct config **basisend = 0;     /* End of list of basis configs */
 
 /* Return a pointer to a new configuration */
-PRIVATE struct config *newconfig(){
+PRIVATE struct config *newconfig(void){
   struct config *newcfg;
   if( freelist==0 ){
     int i;
     int amt = 3;
     freelist = (struct config *)calloc( amt, sizeof(struct config) );
@@ -1275,21 +1275,21 @@
   old->next = freelist;
   freelist = old;
 }
 
 /* Initialized the configuration list builder */
-void Configlist_init(){
+void Configlist_init(void){
   current = 0;
   currentend = &current;
   basis = 0;
   basisend = &basis;
   Configtable_init();
   return;
 }
 
 /* Initialized the configuration list builder */
-void Configlist_reset(){
+void Configlist_reset(void){
   current = 0;
   currentend = &current;
   basis = 0;
   basisend = &basis;
   Configtable_clear(0);
@@ -1395,38 +1395,38 @@
   }
   return;
 }
 
 /* Sort the configuration list */
-void Configlist_sort(){
+void Configlist_sort(void){
   current = (struct config*)msort((char*)current,(char**)&(current->next),
                                   Configcmp);
   currentend = 0;
   return;
 }
 
 /* Sort the basis configuration list */
-void Configlist_sortbasis(){
+void Configlist_sortbasis(void){
   basis = (struct config*)msort((char*)current,(char**)&(current->bp),
                                 Configcmp);
   basisend = 0;
   return;
 }
 
 /* Return a pointer to the head of the configuration list and
 ** reset the list */
-struct config *Configlist_return(){
+struct config *Configlist_return(void){
   struct config *old;
   old = current;
   current = 0;
   currentend = 0;
   return old;
 }
 
 /* Return a pointer to the head of the configuration list and
 ** reset the list */
-struct config *Configlist_basis(){
+struct config *Configlist_basis(void){
   struct config *old;
   old = basis;
   basis = 0;
   basisend = 0;
   return old;
@@ -1530,11 +1530,11 @@
 
 /*
 ** Sort a list of rules in order of increasing iRule value
 */
 static struct rule *Rule_sort(struct rule *rp){
-  int i;
+  unsigned int i;
   struct rule *pNext;
   struct rule *x[32];
   memset(x, 0, sizeof(x));
   while( rp ){
     pNext = rp->next;
@@ -1604,11 +1604,11 @@
   struct rule *rp;
 
   OptInit(argv,options,stderr);
   if( version ){
      printf("Lemon version 1.0\n");
-     exit(0);
+     exit(0);
   }
   if( OptNArgs()!=1 ){
     fprintf(stderr,"Exactly one filename argument is required.\n");
     exit(1);
   }
@@ -2049,11 +2049,11 @@
     exit(1);
   }
   return 0;
 }
 
-int OptNArgs(){
+int OptNArgs(void){
   int cnt = 0;
   int dashdash = 0;
   int i;
   if( argv!=0 && argv[0]!=0 ){
     for(i=1; argv[i]; i++){
@@ -2076,11 +2076,11 @@
   int i;
   i = argindex(n);
   if( i>=0 ) errline(i,0,errstream);
 }
 
-void OptPrint(){
+void OptPrint(void){
   int i;
   int max, len;
   max = 0;
   for(i=0; op[i].label; i++){
     len = lemonStrlen(op[i].label) + 1;
@@ -2305,11 +2305,11 @@
       }
       break;
     case IN_RHS:
       if( x[0]=='.' ){
         struct rule *rp;
-        rp = (struct rule *)calloc( sizeof(struct rule) +
+        rp = (struct rule *)calloc( sizeof(struct rule) +
              sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
         if( rp==0 ){
           ErrorMsg(psp->filename,psp->tokenlineno,
             "Can't allocate enough memory for this rule.");
           psp->errorcnt++;
@@ -2745,11 +2745,11 @@
 void Parse(struct lemon *gp)
 {
   struct pstate ps;
   FILE *fp;
   char *filebuf;
-  unsigned int filesize;
+  unsigned long int filesize;
   int lineno;
   int c;
   char *cp, *nextcp;
   int startline = 0;
 
@@ -2894,11 +2894,11 @@
 ** in the LEMON parser generator.
 */
 static struct plink *plink_freelist = 0;
 
 /* Allocate a new plink */
-struct plink *Plink_new(){
+struct plink *Plink_new(void){
   struct plink *newlink;
 
   if( plink_freelist==0 ){
     int i;
     int amt = 100;
@@ -2995,11 +2995,11 @@
     return 0;
   }
   return fp;
 }
 
-/* Duplicate the input file without comments and without actions
+/* Duplicate the input file without comments and without actions
 ** on rules */
 void Reprint(struct lemon *lemp)
 {
   struct rule *rp;
   struct symbol *sp;
@@ -3146,11 +3146,11 @@
     case RRCONFLICT:
       fprintf(fp,"%*s reduce       %-7d ** Parsing conflict **",
         indent,ap->sp->name,ap->x.rp->iRule);
       break;
     case SSCONFLICT:
-      fprintf(fp,"%*s shift        %-7d ** Parsing conflict **",
+      fprintf(fp,"%*s shift        %-7d ** Parsing conflict **",
         indent,ap->sp->name,ap->x.stp->statenum);
       break;
     case SH_RESOLVED:
       if( showPrecedenceConflict ){
         fprintf(fp,"%*s shift        %-7d -- dropped by precedence",
@@ -3419,11 +3419,11 @@
   if( str[-1]!='\n' ){
     putc('\n',out);
     (*lineno)++;
   }
   if (!lemp->nolinenosflag) {
-    (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
+    (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
   }
   return;
 }
 
 /*
@@ -3464,12 +3464,12 @@
    }
    if( *cp=='\n' ) (*lineno)++;
    fputc(*cp,out);
  }
  fprintf(out,"\n"); (*lineno)++;
- if (!lemp->nolinenosflag) {
-   (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
+ if (!lemp->nolinenosflag) {
+   (*lineno)++; tplt_linedir(out,*lineno,lemp->outname);
  }
  fprintf(out,"}\n"); (*lineno)++;
  return;
 }
 
@@ -3588,11 +3588,11 @@
     }
   }else if( rp->lhsalias==0 ){
     /* There is no LHS value symbol. */
     lhsdirect = 1;
   }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
-    /* The LHS symbol and the left-most RHS symbol are the same, so
+    /* The LHS symbol and the left-most RHS symbol are the same, so
     ** direct writing is allowed */
     lhsdirect = 1;
     lhsused = 1;
     used[0] = 1;
     if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
@@ -3599,11 +3599,11 @@
       ErrorMsg(lemp->filename,rp->ruleline,
         "%s(%s) and %s(%s) share the same label but have "
         "different datatypes.",
         rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
       lemp->errorcnt++;
-    }    
+    }
   }else{
     lemon_sprintf(zOvwrt, "/*%s-overwrites-%s*/",
                   rp->lhsalias, rp->rhsalias[0]);
     zSkip = strstr(rp->code, zOvwrt);
     if( zSkip!=0 ){
@@ -3738,11 +3738,11 @@
   }
 
   return rc;
 }
 
-/*
+/*
 ** Generate code which executes when the rule "rp" is reduced.  Write
 ** the code to "out".  Make sure lineno stays up-to-date.
 */
 PRIVATE void emit_code(
   FILE *out,
@@ -3954,12 +3954,12 @@
 
 /*
 ** Compare to axset structures for sorting purposes
 */
 static int axset_compare(const void *a, const void *b){
-  struct axset *p1 = (struct axset*)a;
-  struct axset *p2 = (struct axset*)b;
+  const struct axset *p1 = (const struct axset*)a;
+  const struct axset *p2 = (const struct axset*)b;
   int c;
   c = p2->nAction - p1->nAction;
   if( c==0 ){
     c = p1->iOrder - p2->iOrder;
   }
@@ -4235,11 +4235,11 @@
   while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;
   fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++;
   fprintf(out, "#define YY_SHIFT_COUNT    (%d)\n", n-1); lineno++;
   fprintf(out, "#define YY_SHIFT_MIN      (%d)\n", mnTknOfst); lineno++;
   fprintf(out, "#define YY_SHIFT_MAX      (%d)\n", mxTknOfst); lineno++;
-  fprintf(out, "static const %s yy_shift_ofst[] = {\n",
+  fprintf(out, "static const %s yy_shift_ofst[] = {\n",
        minimum_size_type(mnTknOfst, lemp->nterminal+lemp->nactiontab, &sz));
        lineno++;
   lemp->tablesize += n*sz;
   for(i=j=0; i<n; i++){
     int ofst;
@@ -4262,11 +4262,11 @@
   n = lemp->nxstate;
   while( n>0 && lemp->sorted[n-1]->iNtOfst==NO_OFFSET ) n--;
   fprintf(out, "#define YY_REDUCE_COUNT (%d)\n", n-1); lineno++;
   fprintf(out, "#define YY_REDUCE_MIN   (%d)\n", mnNtOfst); lineno++;
   fprintf(out, "#define YY_REDUCE_MAX   (%d)\n", mxNtOfst); lineno++;
-  fprintf(out, "static const %s yy_reduce_ofst[] = {\n",
+  fprintf(out, "static const %s yy_reduce_ofst[] = {\n",
           minimum_size_type(mnNtOfst-1, mxNtOfst, &sz)); lineno++;
   lemp->tablesize += n*sz;
   for(i=j=0; i<n; i++){
     int ofst;
     stp = lemp->sorted[i];
@@ -4341,11 +4341,11 @@
     fprintf(out,"\",\n"); lineno++;
   }
   tplt_xfer(lemp->name,in,out,&lineno);
 
   /* Generate code which executes every time a symbol is popped from
-  ** the stack while processing errors or while destroying the parser.
+  ** the stack while processing errors or while destroying the parser.
   ** (In other words, generate the %destructor actions)
   */
   if( lemp->tokendest ){
     int once = 1;
     for(i=0; i<lemp->nsymbol; i++){
@@ -4407,11 +4407,11 @@
 
   /* Generate code which executes whenever the parser stack overflows */
   tplt_print(out,lemp,lemp->overflow,&lineno);
   tplt_xfer(lemp->name,in,out,&lineno);
 
-  /* Generate the table of rule information
+  /* Generate the table of rule information
   **
   ** Note: This code depends on the fact that rules are number
   ** sequentually beginning with 0.
   */
   for(rp=lemp->rule; rp; rp=rp->next){
@@ -4518,11 +4518,11 @@
   out = file_open(lemp,".h","wb");
   if( out ){
     for(i=1; i<lemp->nterminal; i++){
       fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
     }
-    fclose(out);  
+    fclose(out);
   }
   return;
 }
 
 /* Reduce the size of the action tables, if possible, by making use
@@ -4565,11 +4565,11 @@
       if( n>nbest ){
         nbest = n;
         rbest = rp;
       }
     }
-
+
     /* Do not make a default if the number of rules to default
     ** is not at least 1 or if the wildcard token is a possible
     ** lookahead.
     */
     if( nbest<1 || usesWildcard ) continue;
@@ -4722,11 +4722,11 @@
 {
   size = n+1;
 }
 
 /* Allocate a new set */
-char *SetNew(){
+char *SetNew(void){
   char *s;
   s = (char*)calloc( size, 1);
   if( s==0 ){
     extern void memory_error();
     memory_error();
@@ -4828,11 +4828,11 @@
 
 /* There is only one instance of the array, which is the following */
 static struct s_x1 *x1a;
 
 /* Allocate a new associative array */
-void Strsafe_init(){
+void Strsafe_init(void){
   if( x1a ) return;
   x1a = (struct s_x1*)malloc( sizeof(struct s_x1) );
   if( x1a ){
     x1a->size = 1024;
     x1a->count = 0;
@@ -4995,11 +4995,11 @@
 
 /* There is only one instance of the array, which is the following */
 static struct s_x2 *x2a;
 
 /* Allocate a new associative array */
-void Symbol_init(){
+void Symbol_init(void){
   if( x2a ) return;
   x2a = (struct s_x2*)malloc( sizeof(struct s_x2) );
   if( x2a ){
     x2a->size = 128;
     x2a->count = 0;
@@ -5099,19 +5099,19 @@
   }
   return data;
 }
 
 /* Return the size of the array */
-int Symbol_count()
+int Symbol_count(void)
 {
   return x2a ? x2a->count : 0;
 }
 
 /* Return an array of pointers to all data in the table.
 ** The array is obtained from malloc.  Return NULL if memory allocation
 ** problems, or if the array is empty. */
-struct symbol **Symbol_arrayof()
+struct symbol **Symbol_arrayof(void)
 {
   struct symbol **array;
   int i,arrSize;
   if( x2a==0 ) return 0;
   arrSize = x2a->count;
@@ -5123,12 +5123,12 @@
 }
 
 /* Compare two configurations */
 int Configcmp(const char *_a,const char *_b)
 {
-  const struct config *a = (struct config *) _a;
-  const struct config *b = (struct config *) _b;
+  const struct config *a = (const struct config *) _a;
+  const struct config *b = (const struct config *) _b;
   int x;
   x = a->rp->index - b->rp->index;
   if( x==0 ) x = a->dot - b->dot;
   return x;
 }
@@ -5158,11 +5158,11 @@
   }
   return h;
 }
 
 /* Allocate a new state structure */
-struct state *State_new()
+struct state *State_new(void)
 {
   struct state *newstate;
   newstate = (struct state *)calloc(1, sizeof(struct state) );
   MemoryCheck(newstate);
   return newstate;
@@ -5192,11 +5192,11 @@
 
 /* There is only one instance of the array, which is the following */
 static struct s_x3 *x3a;
 
 /* Allocate a new associative array */
-void State_init(){
+void State_init(void){
   if( x3a ) return;
   x3a = (struct s_x3*)malloc( sizeof(struct s_x3) );
   if( x3a ){
     x3a->size = 128;
     x3a->count = 0;
@@ -5286,11 +5286,11 @@
 }
 
 /* Return an array of pointers to all data in the table.
 ** The array is obtained from malloc.  Return NULL if memory allocation
 ** problems, or if the array is empty. */
-struct state **State_arrayof()
+struct state **State_arrayof(void)
 {
   struct state **array;
   int i,arrSize;
   if( x3a==0 ) return 0;
   arrSize = x3a->count;
@@ -5332,11 +5332,11 @@
 
 /* There is only one instance of the array, which is the following */
 static struct s_x4 *x4a;
 
 /* Allocate a new associative array */
-void Configtable_init(){
+void Configtable_init(void){
   if( x4a ) return;
   x4a = (struct s_x4*)malloc( sizeof(struct s_x4) );
   if( x4a ){
     x4a->size = 64;
     x4a->count = 0;



_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Get rid of old-style function declarations/definitions in lemon.c

Dominique Devienne
On Fri, Apr 14, 2017 at 4:54 AM, Guy Harris <[hidden email]> wrote:

> On Apr 13, 2017, at 2:36 AM, Dominique Devienne <[hidden email]>
> wrote:
>


> -PRIVATE struct config *newconfig(){
> +PRIVATE struct config *newconfig(void){
>

Personally I've never been a fan of explicitly "void'ing" arg-less
functions. FWIW.
But I do see others (in the patch's unchanged text), so why not.
Let's now see if DRH applies your patch or not. --DD
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Get rid of old-style function declarations/definitions in lemon.c

Richard Damon
On 4/14/17 4:47 AM, Dominique Devienne wrote:

> On Fri, Apr 14, 2017 at 4:54 AM, Guy Harris <[hidden email]> wrote:
>
>> On Apr 13, 2017, at 2:36 AM, Dominique Devienne <[hidden email]>
>> wrote:
>>
>
>> -PRIVATE struct config *newconfig(){
>> +PRIVATE struct config *newconfig(void){
>>
> Personally I've never been a fan of explicitly "void'ing" arg-less
> functions. FWIW.
> But I do see others (in the patch's unchanged text), so why not.
> Let's now see if DRH applies your patch or not. --DD
>
In C (as opposed to C++), it is the only way to provide a real prototype
for such a function. The empty parameter list means with an unspecified
parameter list in C.

--
Richard Damon

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Get rid of old-style function declarations/definitions in lemon.c

Guy Harris
On Apr 14, 2017, at 3:59 AM, Richard Damon <[hidden email]> wrote:

> In C (as opposed to C++), it is the only way to provide a real prototype for such a function. The empty parameter list means with an unspecified parameter list in C.

Exactly.  Perhaps some future C standard will finally get rid of that support for legacy C, but, for now, if you want to say "this function takes no arguments", you have no choice but to declare it as noargs(void) - and I think explicitly declaring that is a Very Good Thing, as it means that the compiler will reject calls to the function that pass it arguments, as it should.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users