Aller au contenu principal

modules

The way to implement new functions in Extenso

MODULES

NAME

modules - The way to implement new functions in Extenso

SYNOPSIS

modules

DESCRIPTION

The first thing to setup is the name of the module in the configuration file:

Module exemple {
        Library : "/usr/local/lib/libsnexemple.so"
        Init : "snexemple_init"
        vara : "valuea"
        varb : "valueb"
}

The value vara and varb are parameters for the module. You can add as many as you want.

The function snexemple_init is the initialization routine which exposes all functions:

sncode
snexemple_init(snconfig *c, snmodules *m) {
        SNDEBUG( "snexemple_init(c=%x,m=%x,%s)\n", c, m, m->library);

        apr_hash_set(c -> sfcts, "twice", 5, (void *)snexemple_twice);

        SNDEBUG("var %p vara = %s\n", m -> module_var, (char *) apr_hash_get(m -> module_var, "vara", 4));
        SNDEBUG("return from snexemple_init\n");
        return snok;
}

This example exposes the function twice or addw the twice function to the hash array of all predefined functions.

The initialization of the file is:

#include 

#define SNDEBUG(x...) { fprintf(stderr, "Pid %d file %s line %d ", getpid(), __FILE__, __LINE__); fprintf(stderr, x); }
#define SNERROR(p, errcode, x...) snexec_error(p, errcode, x);

int
snexemple_twice(snfctcall *fc) {
        snparser *p = fc -> p;          /* Parser pointer */
        snvalue *s = fc -> s;           /* Stack */
        bool fctcb = fc -> fctcb;       /* Is this a callback */
        int nbargs = fc -> nbargs;      /* Number of args */
        int *sp = fc -> sp;             /* Stack pointer */
...

This defines the SNERROR macros and SNDEBUG. If the user doesn’t want debugging information, then one needs to redefine SNDEBUG to nothing.

The function twice is responded to do the job. It must check the arguments, see if there is an error, and do the job. It must clear the stack of its argument and MUST return a new item on the stack. Clearing the stack is done with:

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

Returning an element on the stack is done with:

v = &s[*sp-1];
v -> typeval = SNIVAL;
v -> ival = i >> 2;
v -> narg = false;

The arguement fctcb is a boolean that determine if this function is call as a callback or as a function.

If this function is call as a callback, then the following variables are also defines:

  • p → cb → nb : loop counter starting at 0
  • p → cb → nb1 : loop counter starting at 1
  • p → cb → var : Pointer to variable of type snvalue *
  • p → cb → varname : Name of variable

RETURN

It returns snok if there is no error. It returns SNERROR(p, snerrexec, "Function twice required 1 argument.\n"); if there is an error

EXAMPLES

Full codes of this example:

/*----------------------------------------------------------------------------*/
/*!

 \file

 This file is a module example.

 \version       1.0 Initial Version

 \date          Sun Feb  2 17:17:54 2003

 \author        Pierre Laplante

 \verbatim
                Copyright © 2011
                SedNove Inc.
                439 OAK
                St-Lambert, QC, Canada
                All rights reserved.
                Wed Feb  5 22:09:31 2003
                Pierre.Laplante@sednove.com
 \endverbatim

*/
/*----------------------------------------------------------------------------*/

#include 

#define SNDEBUG(x...) { fprintf(stderr, "Pid %d file %s line %d ", getpid(), __FILE__, __LINE__); fprintf(stderr, x); }
#define SNERROR(p, errcode, x...) snexec_error(p, errcode, x);

/*----------------------------------------------------------------------------*/
///
/// Fonction twice
///
/*----------------------------------------------------------------------------*/

int
snexemple_twice(snfctcall *fc) {
        snparser *p = fc -> p;          /* Parser pointer */
        snvalue *s = fc -> s;           /* Stack */
        bool fctcb = fc -> fctcb;       /* Is this a callback */
        int nbargs = fc -> nbargs;      /* Number of args */
        int *sp = fc -> sp;             /* Stack pointer */
  int i,j;
  snvalue *v;

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

  if (nbargs != 1)
        return SNERROR(p, snerrexec, "Function twice required 1 argument.\n");

  if (fctcb)
        return SNERROR(p, snerrexec, "Function twice can't be used in a callback.\n");

  v = &s[*sp-1];
  if (v -> typeval != SNIVAL)
        return SNERROR(p, snerrexec, "Function twice expected an integer.\n");

  i = v -> ival;
  SNDEBUG("value = %d\n", v -> ival);

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

  v = &s[*sp-1];
  v -> typeval = SNIVAL;
  v -> ival = i << 1;
  v -> narg = false;

  return snok;

}

/*----------------------------------------------------------------------------*/
///
/// Fonction decr
///
/*----------------------------------------------------------------------------*/

int
snexemple_decr(snfctcall *fc) {
        snparser *p = fc -> p;          /* Parser pointer */
        snvalue *s = fc -> s;           /* Stack */
        bool fctcb = fc -> fctcb;       /* Is this a callback */
        int nbargs = fc -> nbargs;      /* Number of args */
        int *sp = fc -> sp;             /* Stack pointer */
  int i,j;
  snvalue *v;

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

  if (nbargs != 1)
        return SNERROR(p, snerrexec, "Function desc required 1 argument.\n");

  if (!fctcb)
        return SNERROR(p, snerrexec, "Function decr can't be used as a function.\n");

  v = &s[*sp-1];
  if (v -> typeval != SNRVAL)
        return SNERROR(p, snerrexec, "Function decr expected a variable.\n");
  v = v -> rval;

  if (v -> typeval != SNIVAL)
        return SNERROR(p, snerrexec, "Function decr expected a integer variable.\n");


  v -> ival--;
  i = v -> ival;
  SNDEBUG("value of %s is now = %d\n", p -> cb -> varname, v -> ival);

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

  v = &s[*sp-1];
  v -> typeval = SNIVAL;
  v -> ival = i;
  v -> narg = false;

  p -> cb -> var -> ival = i * 2;
  p -> cb -> var -> typeval = SNIVAL;

  return snok;

}

/*------------------------------------------------------------------------------*/
/*!

 \brief         snexemple_init

 Initialise functions for this module

 \author        Pierre Laplante

 \date          Wed Aug 13 15:50:20 2003

*/
/*------------------------------------------------------------------------------*/

sncode
snexemple_init(snconfig *c, snmodules *m) {

  SNDEBUG( "snexemple_init(c=%x,m=%x,%s)\n", c, m, m->library);

  apr_hash_set(c -> sfcts, "twice", 5, (void *)snexemple_twice);
  apr_hash_set(c -> sfcts, "decr", 4, (void *)snexemple_decr);

  SNDEBUG("return from snexemple_init\n");
  return snok;
}

SEE ALSO

{{ include("includes/modules.sn") }}

AUTHOR

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

MODIFICATIONS

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

1.1 2016-04-06 laplante@sednove.com variable for module configuration has been added from version 5.56

Edit

© 2024 extenso Inc. All rights reserved.