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