Goto main content

cfunction

Describes how to add new functions in C

CFUNCTION

NAME

cfunction - Describes how to add new functions in C

SYNOPSIS

See Description

DESCRIPTION

This page is designed to describe how to add new functions in C. Functions in C can be used in a callback or as a standalone function. C functions are called with the following signature:

int function(snparser *p, int nbargs, int *sp, snvalue *s, bool fctcb);

Within structure snparser, the structure callback contains the following variables:

typedef enum {
  sncb_start=0,                                 /* Initialisation */
  sncb_running,                                 /* We have allocated memory and we need to release if */
  sncb_finish,                                  /* We do not need to release memory */
  sncb_release,                                 /* We need to release memory */
} sncallback_state;

typedef  struct _callback {
  snvalue *v_nb, *v_nb1;                        /* Variable for nb and nb1 */
  snvalue *v_var, *v_loop;                      /* Variable for loop and var */
  struct _callback *next, *prev;                /* Double linked list */
  bool used;                                    /* In used */
  int nb;                                       /* loop counter from 0 */
  int nb1;                                      /* loop counter from 1 */
  snvalue *var;                                 /* Pointer to the current variable */
  void *parm;                                   /* Parameter for the callback to hold data  */
  apr_pool_t *p;                                /* old pool */
  sncallback_state state;                       /* State of loop */
  int (*f) ();                                  /* Function of call */
} callback;

If the function is used in a callback, the variable fctcb will be set to true. In that case, one can use the structure callback.

A function must return a status code. Status codes can be: - snok, - snerror, - sneof, - snnauth, - sndeclined, - snerrparse, /* Parse error / - snerrexec, / Execution error / - sndivundef, / Division by undefined / - sndivzero, / Division by zero / - sndivnull, / Division by null / - snmodundef, / Modulo by undefined / - snmodzero, / Modulo by zero / - snmodnull, / Modulo by null / - snerrsql, / SQL Error */

If the function is a callback, then the returned value on the stack must be true or false: true to continue the callback, false to stop it.

If a function is a callback, then it's possible the function is break in a middle. If you set the following variable:

if (p ->cb)
  p -> cb -> state = sncb_running;

then, if a break is called, your function will be called:

if (fctcb && p -> cb -> state == sncb_release) {
  cb = (sndb_sql_cb *) p -> cb -> parm;
  sqlret = cb -> sqlret;
  sndbi_free(sqlret) ;
  p -> cb -> state = sncb_finish;
  return snok;
}

Arguments for the function are put on the stack "s" point by the stack pointer "sp". To get the first argument one can use:

v = &s[*sp-1]; 

To remove all arguments on the stack, one can use:

(*sp)-=(nbargs-1); 

To return an argument, one can use:

v = &s[*sp-1];
snexec_initvar(p,v); // Init variable
v -> typeval = SNIVAL;
v -> ival = mbstowcs(NULL,str,0); 

The name of the function is in the structure snparser; so p → fctname returns the function name.

EXAMPLES

Note: In the following examples, the _ between the { should be removed to make it work.

int
snstr_length(snparser *p, int nbargs, int *sp, snvalue *s, bool fctcb) {
  int i, n;
  snvalue *v, *w;
  char *str;
  int retcode;

  SNDEBUG("snfonctions_length(p=%x, nbargs=%d, sp=%d, s=%x)\n", (unsigned int)p, nbargs, *sp, s);

  if (nbargs != 1)
        return SNERROR(p, snerrexec, "Invalid number of arguments\n");

  if (fctcb)
        return SNERROR(p, snerrexec, "This function cannot be used in a callback\n");

  v = &s[*sp-1];
  if (v -> typeval == SNRVAL)
        v = v -> rval;

  retcode = snfonctions_get_sval(p, v, &str);
  if (retcode != snok)
        return SNERROR(p, snerrexec, "Parameter cannot be a string.\n");

  (*sp)-=(nbargs-1);
  v = &s[*sp-1];
  snexec_initvar(p, v);
  v -> typeval = SNIVAL;
  v -> ival = mbstowcs(NULL,str,0);

  return snok;
}

SEE ALSO

AUTHOR

Written by Pierre Laplante and Caroline Laplante, <laplante@sednove.com>

MODIFICATIONS

1.0 2014-09-09 21:24:14 laplante@sednove.com

Edit

© 2024 extenso Inc. All rights reserved.