Confusion on sqlite3 struct in sqlite3 source code - c

In the function
static int sqlite3Prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
Vdbe *pReprepare, /* VM being reprepared */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
) {
...
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
...
assert( !db->mallocFailed );
...
}
I know sqlite3 is just a fake struct declared as
typedef struct sqlite3 sqlite3;
without any body. I know sqlite3 * is usually is cast to a Vdbe*.
But here, db is of the type of sqlite3*, how can db->malloFailed exist? Why doesn't the compiler complain?
There is similar situation with sqlite3_stmt:
typedef struct sqlite3_stmt sqlite3_stmt;
with no body. I guess sqlite3_stmt is a syntax tree of parsed SQL statements. I would like to see the structure of it. However, the type is hidden so deeply using this weird pattern that I can't see what it is.
Even Vdbe is the same situation...
typedef struct Vdbe Vdbe;
Where on earth is the real struct?

sqlite3 is not a fake struct; the sqlite.h file just does not define its body.
Its definition is in the sqliteInt.h file (which is also part of the sqlite3.c amalgamation):
/*
** Each database connection is an instance of the following structure.
*/
struct sqlite3 {
sqlite3_vfs *pVfs; /* OS Interface */
struct Vdbe *pVdbe; /* List of active virtual machines */
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
...
u8 mallocFailed; /* True if we have seen a malloc failure */
...

Related

Get the name of a coll object in Max C API

I am writing a Max MSP external.
I am lost in Max C API documentation since hours and couldn't find a way to get the name of a coll object from Max C API.
https://cycling74.com/sdk/max-sdk-8.0.3/html/index.html
If the object is | coll foo | , foo is the symbol I want to get.
I am able to iterate over a patcher and get pointers to all boxes and then to objects by calling jbox_get_object() with pointers to boxes. I tried getting many attributes of the objects I got and everything works ok.
I can't seem to find where the data I want to get is stored and what is it called.
I would appreciate some help.
Thank you.
[coll] is very sparsely documented, you should ask on the Cycling74 dev-forum. Below is what I do in [posit] after traversing the patcher to find a coll’s box. hth /*j
#include “coll.h”
<snip>
t_object *o;
t_coll *collob;
t_object *jb;
t_symbol *collname;
<snip>
o = jbox_get_object(jb);
collob = (t_coll *)o;
collname = (t_symbol *)collob->c_x->c_sym;
</snip>
Thank you user12106422! This is how I have implemented this in my iterator function and it works perfectly.
#include "coll.h"
//in your iterator function ..
long patcher_iterator(<replace this with your external type> *x, t_object *b) {
//check if object is a coll
if(strncmp(object_classname( jbox_get_object(b) )->s_name, "coll",4) == 0){
t_coll *collobject;
t_symbol *collname;
collob = (t_coll *)jbox_get_object(b);
collname = (t_symbol *)collobject->c_x->c_sym;
post("--The name of the coll is (%s) ", collname->s_name);
}
}
I would also like to share coll.h here for common benefit.
/* -------- coll.c -- the collection object --------------- */
#include "ext.h"
// #include "edit.h"
#include "ext_wind.h"
#include "ext_common.h"
#include "ext_strings.h"
#include "ext_critical.h"
#define C_EMBED 1
/* ddz 06/09/94:
* fixed interspersed (entremele) use of next and prev messages
* added assistance for third outlet
* prototyped functions and removed voids
* fixed truncating on sorts
*/
/* sde use to fill the read and write flags */
#define FILE_DIALOG 1 /* use dialogs to get file name */
#define FILE_NAMED 2 /* symbol specifies file name */
#define Index_Integer 1
#define Index_Symbol 2
typedef struct celem { /* doubly linked list element */
short e_size;
short e_extra;
long e_index;
t_symbol *e_assoc;
struct celem *e_next;
struct celem *e_prev;
t_atom e_data[1]; /* dummy */
} t_celem;
typedef struct xcoll {
t_object c_ob;
void *c_data; // linklist
//t_celem c_head; /* head of list elements */
t_celem *c_next; /* element to be returned by "next" */
t_celem *c_prev; /* element to be returned by "prev" */
void *c_out2; /* next "end" signal outlet */
char c_read,c_write; /* flags for reading & writing */
char c_freeing,c_saveme;
char c_embed; /* embed in owning patcher? */
t_symbol *c_sym; /* associated symbol? */
struct ed *c_edit; /* edit window */
short c_refcount; /* reference count */
struct coll *c_refcoll; /* list of "colls" that reference this xcoll */
/* sde filename, volume, and MAX type */
t_symbol *c_fn;
short c_vol;
short c_bin;
long c_type; /* type of the file that was read in */
short c_modified;
long c_filetype; /* for filetype message -- allowed types */
long c_modcount;
} t_xcoll;
typedef struct coll {
t_object c_ob;
t_xcoll *c_x;
t_symbol *c_sym;
void *c_out2;
/* sde third outlet bangs after reading data */
void *c_out3;
void *c_out4;
struct coll *c_nextref; /* next in the list of colls that share this coll's xcoll */
void *c_owner;
long c_nosearch;
} t_coll;

How implement PostgreSQL extension using PostGIS types

I would like to create a new data type for PostGIS, but I have some difficulties. Here's what I've done so far:
/* PostgreSQL */
#include <postgres.h>
#include <liblwgeom.h>
#include <lwgeom_pg.h>
#include <utils/timestamp.h>
struct trajectory_elem
{
// int32 dummy; /* Padding to make it double aligned. */
Timestamp time_obj;
LWGEOM *geom_elem; /* Geometry Object - */
};
#define DatumGetTrajectoryElem(X) ((struct trajectory_elem*) PG_DETOAST_DATUM(X))
#define PG_GETARG_TRAJECTELEM_TYPE_P(n) DatumGetTrajectoryElem(PG_GETARG_DATUM(n))
#define PG_RETURN_TRAJECTELEM_TYPE_P(x) PG_RETURN_POINTER(x)
extern Datum create_trajectory_elem(PG_FUNCTION_ARGS);
extern Datum trajectory_elem_in(PG_FUNCTION_ARGS);
extern Datum trajectory_elem_out(PG_FUNCTION_ARGS);
.....
PG_FUNCTION_INFO_V1(create_trajectory_elem);
Datum
create_trajectory_elem(PG_FUNCTION_ARGS)
{
Timestamp time_geom = PG_GETARG_TIMESTAMP(0);
GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
struct trajectory_elem *trje = (struct trajectory_elem *) palloc(sizeof(struct trajectory_elem));
trje->time_obj = time_geom;
/*get lwgeom from GSERIALIZED varlena*/
trje->geom_elem = lwgeom_from_gserialized(geom);
if ( lwgeom_is_empty(trje->geom_elem))
{
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_NULL();
}
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_TRAJECTELEM_TYPE_P(trje);
}
Is the way I'm creating my trajectory_elem structure correct?
Can I simply point to the LWGEO type? Or.. Should I create a new type like the GSERIALIZED ?
How would the input and output functions for this type be? Could I use the functions already implemented by PostGIS?
I tested some implementations for the I / O functions but when it arrives in PG_RETURN_TRAJECTELEM_TYPE_P (create_trajectory_elem), the server drops. So they were probably wrong

Change Struct module pointer

Good day all, I'd like some help to change a small section in this C program which I have licensed back in the early 90's. Some of you may be familiar with it, it's called MajorBBS and as you probably have guess it is bbs software.
In the header file majorbbs.h we have
extern
struct module { /* module interface block */
char descrp[MNMSIZ]; /* description for main menu */
int (*lonrou)(); /* user logon supplemental routine */
int (*sttrou)(); /* input routine if selected */
void (*stsrou)(); /* status-input routine if selected */
int (*injrou)(); /* "injoth" routine for this module */
int (*lofrou)(); /* user logoff supplemental routine */
void (*huprou)(); /* hangup (lost carrier) routine */
void (*mcurou)(); /* midnight cleanup routine */
void (*dlarou)(); /* delete-account routine */
void (*finrou)(); /* finish-up (sys shutdown) routine */
} **module;
Also in the majorbbs.h we have some code that defines the menu variables
extern
struct usrmnu { /* user's menuing-specific variables */
char curpag[PNMSIZ]; /* current menu page */
char parpag[PNMSIZ]; /* parent menu page */
char selchrs[MAXSEL]; /* select characters currently available */
char pages[MAXSEL][PNMSIZ]; /* pages or file names for select chars */
char optdsp[MAXSEL]; /* instructions on how to display options */
int keyreq[MAXSEL]; /* key required for each select character */
FILE *fp; /* pointer to file currently being viewed */
char mnuttl[TITLSZ]; /* menu page title */
} *mnuusr;
Then in the majorbbs.c file we have
struct module module00={ /* module interface block */
"Menuing System", /* description for main menu */
NULL, /* user logon supplemental routine */
mainu, /* input routine if selected */
musthn, /* status-input routine if selected */
NULL, /* "injoth" routine for this module */
NULL, /* user logoff supplemental routine */
loscar, /* hangup (lost carrier) routine */
midnit, /* midnight cleanup routine */
NULL, /* delete-account routine */
mjrfin /* finish-up (sys shutdown) routine */
};
What I'd like is to change the value of the descrp here which is defined as "Menuing System" to something more dynamic like the Menu the user is currently on.
From the code here I think it would be mnuusr->curpag which is where the pointer is pointing to I think.
So I'm thinking of a routine. I am by no means a programmer and I've been there many sites to look for examples of how to do such a thing. I've searched here for the last couple days (before posting this). I saw some things
that sparked a "Hey this might work" but I ended up with compiler errors (more on that in a bit)
What I did was make a routine like
char *
mydescrp
{
if (strcmp(module00.descrp,"Menuing System" ) == 0 ) {
mnuusr=mnuoff(usrnum);
return(mnuusr->mnuttl);
}
}
Then if I change the module00 call above to
struct module module00={
mydescrp, /* My change */
NULL,
mainu,
musthn,
NULL,
NULL,
loscar,
midnit,
NULL,
mjrfin
};
When I compile I get some error that says:
Initalization not fully bracketed
the list goes on from there. There are some further initialization later on in majorbbs.c and will gladly supply them if you need. I am sure one would be.
int
register_module( /* register a module for online use */
struct module *mod) /* pointer to a module block */
{
if (strlen(mod->descrp) > MNMSIZ-1) {
catastro("MODULE NAME \"%s\" TOO LONG!",mod->descrp);
}
if (mod->stsrou == NULL) {
mod->stsrou=dfsthn;
}
if (nmods == 0) {
module=(struct module **)alcmem(sizeof(struct module *));
mdstats=(struct mdstats *)alcmem(sizeof(struct mdstats));
}
else {
module=(struct module **)alcrsz(module,sizeof(struct module *)*nmods,
sizeof(struct module *)*(nmods+1));
mdstats=(struct mdstats *)alcrsz(mdstats,sizeof(struct mdstats)*nmods,
sizeof(struct mdstats)*(nmods+1));
}
module[nmods]=mod;
setbtv(mstbb);
if (qeqbtv(mod->descrp,0)) {
gcrbtv(&mdstats[nmods],0);
}
else {
setmem(&mdstats[nmods],sizeof(struct mdstats),0);
strcpy(mdstats[nmods].mdname,mod->descrp);
}
rstbtv();
return(nmods++);
}
From MENUING.C mnuoff routine
struct usrmnu *
mnuoff( /* get pointer to user's menu info */
int unum) /* user number to grab */
{
#ifdef PHARLAP
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
#ifdef ECLIPSE
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
return((struct usrmnu *)(muusrs+(unum*(long)sizeof(struct usrmnu))));
#endif
#endif
}
Is this the routine to change for some newly code? I am simply at a loss on how to go about this. If you need more code let me know.
I even went as far as asking for help from other majorbbs programmers on usenet but this software is 20 years + old so I don't think anyone uses it anymore let alone modify code anymore. I would think since it's still C someone might have an idea to help me out. I am trying to create a new revive with some small modifications. This being one of two.
Thanks for any help.
It looks like the descrp field in struct module is expecting a char[] (or a string), and you're giving it a char *() (function returning a string) instead.
Perhaps what you want to do is not call the mydescrp function in the declaration of module00, but manually perform the check in register_module:
int register_module(struct module *mod) {
if (strcmp(mod->descrp, "Menuing System") == 0) {
struct usrmnu *menu = mnuoff(usrnum);
// Copy as much of the title to the menu description as possible.
strncpy(mod->descrp, menu->mnuttl, MNMSIZ-1);
// Terminate the string in case the title was too long.
mod->descrp[MNMSIZ-1] = '\0';
}
// Rest of method.
}

Warning: parameter names (without types) in function declaration

Rookie question FYI.
Whenever I compile/run the code, extern tolayer2(rtpktTo1); I receive a warning.
The warning reads, as in the title, Warning: parameter names (without types) in function declaration
Any help appreciated.
node0.c
extern struct rtpkt {
int sourceid; /* id of sending router sending this pkt */
int destid; /* id of router to which pkt being sent
(must be an immediate neighbor) */
int mincost[4]; /* current understanding of min cost to node 0 ... 3 */
};
/* Create routing packets (rtpkt) and send to neighbors via tolayer2(). */
struct rtpkt rtpktTo1;
rtpktTo1.sourceid = 0;
rtpktTo1.destid = 1;
rtpktTo1.mincost[0] = minCost[0];
rtpktTo1.mincost[1] = minCost[1];
rtpktTo1.mincost[2] = minCost[2];
rtpktTo1.mincost[3] = minCost[3];
extern tolayer2(rtpktTo1);
prog3.c
tolayer2(packet)
struct rtpkt packet;
{
/* This has a lot of code in it */
}
The assignments to rkpktTo1.* are not apparently in a function or declaration, unless this is a code fragment. Wrap them in a function. The warning is a bit misleading.
The declaration of tolayer2() should have a return type as well as a parameter type. Since there isn't one, int is assumed. This may not be what is intended, but it should compile without warnings and errors:
node0.c
struct rtpkt {
int sourceid; /* id of sending router sending this pkt */
int destid; /* id of router to which pkt being sent
(must be an immediate neighbor) */
int mincost[4]; /* current understanding of min cost to node 0 ... 3 */
};
/* Create routing packets (rtpkt) and send to neighbors via tolayer2(). */
void function () {
struct rtpkt rtpktTo1;
rtpktTo1.sourceid = 0;
rtpktTo1.destid = 1;
rtpktTo1.mincost[0] = minCost[0];
rtpktTo1.mincost[1] = minCost[1];
rtpktTo1.mincost[2] = minCost[2];
rtpktTo1.mincost[3] = minCost[3];
}
extern void tolayer2(struct rtpkt *rtpktTo1);
prog3.c
void
tolayer2(struct rtpkt *packet)
{
/* This has a lot of code in it */
}
Passing a structure by value is often not appropriate, so I have changed it to pass by reference.
In prog3.c
tolayer2(packet)
struct rtpkt packet;
{ /* ... */ }
This is old syntax (very old: before ANSI standardized C in 1989), but perfectly legal in C89 and C99. Don't use it though: prefer
int tolayer2(struct rtpkt packet)
{ /* ... */ }
In the declaration extern tolayer2(rtpktTo1);, rtpktTo1 is a parameter name (like the error says), while you should give a type there:
extern tolayer2(struct rtpkt);
or
extern tolayer2(struct rtpkt *);
or
extern tolayer2(struct rtpkt const *);
or similar, since that is what the compiler needs to know about your function before compiling client code. The parameter name is useless to the compiler at this point and therefore optional.
(And really, you should add a return type as well, and note that extern has no meaning in your struct definition.)

Compiler Error in C: expected ')' before '*' token

As the title says, keep getting this error when trying to compile. From Googling this error people have said that it is not declared in the header file but my function is static and it is not in a header file, I prototyped it.`
#include <recGbl.h>
#include <devSup.h>
#include <devLib.h>
#include <drvIpac.h>
#include <dbScan.h>
#include <epicsExport.h>
static int cardinit(cardinfo *card); // <-- line that gives the error
typedef struct cardinfo{
struct cardinfo *next;
struct io_mem_read *pMem; /* IP register (A16) mem address */
word *rambase; /* RAM conversion memory mem address*/
int isconfigured;
int doram; /* 1 if we are using the RAM to output data.
0 if we are writing to registers (AO style) */
int cardnum;
int vmeslotnum;
int ipslotnum;
/* these values mirror the hardware registers */
word csr;
word offset;
word numconv;
word clockrate;
word vectnum;
word dacval[MAXSIGNAL];
word oldispresent;
/* used to detect a reinsertion of a carrier card.
see subroutine ispresent() below. */
/* use to update process variables */
IOSCANPVT ioscanpvt;
} cardinfo;
static int Hy8402init(int vmeslot, int ipslot, int clockrate) {
cardinfo *card;
card->vmeslotnum = vmeslot;
card->ipslotnum = ipslot;
card->cardnum = 1;
card->clockrate = clockrate;
card->vectnum = 10;
cardinit(card);
return TRUE;
}
static int cardinit(cardinfo *card){
word rprobe;
int res;
volatile word *ramptr;
card->pMem= ipmBaseAddr(card->vmeslotnum,
card->ipslotnum,ipac_addrIO);
if (card->pMem==NULL){
printf("Error in %s",devstr);
printf( "%s: Cannot determine base address\n",devstr);
return FALSE;
}
res=devReadProbe(sizeof (word),(char *) card->pMem,(char *) &rprobe);
if (res!=OK){
printf("%s: NO DEVICE at %x (vmeslot %d, ipslot %d)\n",devstr,
(int)card->pMem,
card->vmeslotnum,card->ipslotnum);
return FALSE;
}
return TRUE;
}
`
cardinfo struct is still undefined on the line with error. Put a forward declaration before it:
struct cardinfo;
static int cardinit(struct cardinfo *card);
This line of code:
static int cardinit(cardinfo *card);
should be added after the definition of your cardinfo structure.
You need to put the line
static int cardinit(cardinfo *card);
after the definition of the cardinfo structure.
At that line, the compiler doesn't yet know that cardinfo is a struct. Precede it with the line struct cardinfo;
You have declared a function which has a input variable of a type which the compiler is not aware when it parses it. i.e the struct defintion follows your function declaration.
So please do a forward declaration of the structure when you want to compile such code.
In computer programming, a forward declaration is a declaration
of an identifier (denoting an entity such as a type, a variable, or a
function) for which the programmer has not yet given a complete definition.
This link has a nice article on when full declarations are not required.

Resources