⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 how_to_add

📁 Calc Software Package for Number Calc
💻
📖 第 1 页 / 共 2 页
字号:
Guidelines for adding custom functions--------------------------------------Step 0: Determine if is should it be done?    The main focus for calc is to provide a portable platform for    multi-precision calculations in a C-like environment.  You should    consider implementing algorithms in the calc language as a first    choice.  Sometimes an algorithm requires use of special hardware, a    non-portable OS or pre-compiled C library.	In these cases a custom    interface may be needed.    The custom function interface is intended to make is easy for    programmers to add functionality that would be otherwise    un-suitable for general distribution.  Functions that are    non-portable (machine, hardware or OS dependent) or highly    specialized are possible candidates for custom functions.    So before you go to step 1, ask yourself:	+ Can I implement this as a calc resource file or calc shell script?	    If Yes, write the shell script or resource file and be done with it.	    If No, continue to the next question ...	+ Does it require the use of non-portable features,	  OS specific support or special hardware?	    If No, write it as a regular builtin function.	    If Yes, continue to step 1 ...Step 1: Do some background work    First ... read this file ALL THE WAY THROUGH before implementing    anything in Steps 2 and beyond!    If you are not familiar with calc internals, we recommend that    you look at some examples of custom functions.  Look at the    the following source files:	custom.c	custom.h	custom/custtbl.c	custom/c_*.[ch]	custom/*.cal	help/custom		(or run:  calc help custom)    You would be well advised to look at a more recent calc source    such as one available in from the calc version archive.    See the following for more details:	help/archive		(or run:  calc help archive)Step 2: Name your custom function    We suggest that you pick a name that does not conflict with    one of the builtin names.  It makes it easier to get help    via the help interface and avoid confusion down the road.    You should avoid picking a name that matches a file or    directory name under ${HELPDIR} as well.  Not all help    files are associated with builtin function names.    For purposes of this file, we will use the name 'curds'    as our example custom function name.Step 3: Document your custom function    No this step is NOT out of order.  We recommend that you write the    help file associated with your new custom function EARLY.  By    experience we have found that the small amount of effort made to    write "how the custom function will be used" into a help file pays    off in a big way when it comes to coding.  Often the effort of    writing a help file will clarify fuzzy aspects of your design.    Besides, unless you write the help file first, it will likely never    be written later on.  :-(    OK ... we will stop preaching now ...    [[ From now on we will give filenames relative to the custom directory ]]    Take a look at one of the example custom help files:	custom/devnull	custom/argv	custom/help	custom/sysinfo    You can save time by using one of the custom help files    as a template.  Copy one of these files to your own help file:	cd custom	cp sysinfo curds    and edit it accordingly.Step 4: Write your test code    No this step is NOT out of order either.  We recommend that you    write a simple calc script that will call your custom function and    check the results.    This script will be useful while you are debugging your code.  In    addition, if you wish to submit your code for distribution, this    test code will be an import part of your submission.  Your test    code will also service as additional for your custom function.    Oops ... we said we would stop preaching, sorry about that ...    You can use one of the following as a template:	custom/argv.cal	custom/halflen.cal    Copy one of these to your own file:	cd custom	cp halflen.cal curds.cal    and exit it accordingly.  In particular you will want to:	remove our header disclaimer (or put your own on)	change the name from halflen() to curds()	change the comment from 'halflen - determine the length ...' to	'curds - brief description about ...'	change the print statement near the very bottom from:		print "halflen(num) defined";	to:		print "curds( ... args description here ...) defined";Step 5: Write your custom function    By convention, the files we ship that contain custom function    interface code in filenames of the form:	c_*.c    We suggest that you use filenames of the form:	u_*.c    to avoid filename conflicts.    We recommend that you use one of the c_*.c files as a template.    Copy an appropriate file to your file:	cd custom	cp c_argv.c u_curds.c    Before you edit it, you should note that there are several important    features of this file.	a) All of the code in the file is found between #if ... #endif:		/*		 * only comments and blank lines at the top		 */		#if defined(CUSTOM)		... all code, #includes, #defines etc.		#endif /* CUSTOM */	   This allows this code to 'go away' when the upper Makefile	   disables the custom code (because ALLOW_CUSTOM no longer	   has the -DCUSTOM define).	b) The function type must be:		/*ARGSUSED*/		VALUE		u_curds(char *name, int count, VALUE **vals)	   The 3 args are passed in by the custom interface	   and have the following meaning:		name	The name of the custom function that			was called.  In particular, this is the first			string arg that was given to the custom()			builtin.  This is the equivalent of argv[0] for			main() in C programming.			The same code can be used for multiple custom			functions by processing off of this value.		count	This is the number of additional args that			was given to the custom() builtin.  Note			that count does NOT include the name arg.			This is similar to argc except that count			is one less than the main() argc interface.			For example, a call of:			    custom("curds", a, b, c)			would cause count to be passed as 3.		vals	This is a pointer to an array of VALUEs.			This is the equivalent of argv+1 for			main() in C programming.  The difference			here is that vals[0] refers to the 1st			parameter AFTER the same.			For example, a call of:			    custom("curds", a, b, c)			would cause vals to point to the following array:			    vals[0]  points to	a			    vals[1]  points to	b			    vals[2]  points to	c	   NOTE: If you do not use any of the 3 function parameters,	   then you should declare that function parameter to be UNUSED.	   For example, if the count and vals parameters were not used	   in your custom function, then your declaraction should be:		/*ARGSUSED*/		VALUE		u_curds(char *name, int UNUSED count, VALUE UNUSED **vals)	c) The return value is the function must be a VALUE.	   The typical way to form a VALUE to return is by declaring	   the following local variable:		VALUE result;	/* what we will return */	d) You will need to include:		#if defined(CUSTOM)		/* any #include <foobar.h> here */		#include "../have_const.h"		#include "../value.h"		#include "custom.h"		#include "../have_unused.h"	    Typically these will be included just below any system	    includes and just below the #if defined(CUSTOM) line.    To better understand the VALUE type, read:	../value.h    The VALUE is a union of major value types found inside calc.    The v_type VALUE element determines which union element is    being used.	  Assume that we have:	VALUE *vp;    Then the value is determined according to v_type:	vp->v_type	the value is	which is a	type defined in	----------	------------	----------	---------------	V_NULL		(none)		n/a		n/a	V_INT		vp->v_int	long		n/a	V_NUM		vp->v_num	NUMBER *	../qmath.h	V_COM		vp->v_com	COMPLEX *	../cmath.h	V_ADDR		vp->v_addr	VALUE *		../value.h	V_STR		vp->v_str	char *		n/a	V_MAT		vp->v_mat	MATRIX *	../value.h	V_LIST		vp->v_list	LIST *		../value.h	V_ASSOC		vp->v_assoc	ASSOC *		../value.h	V_OBJ		vp->v_obj	OBJECT *	../value.h	V_FILE		vp->v_file	FILEID		../value.h	V_RAND		vp->v_rand	RAND *		../zrand.h	V_RANDOM	vp->v_random	RANDOM *	../zrandom.h	V_CONFIG	vp->v_config	CONFIG *	../config.h	V_HASH		vp->v_hash	HASH *		../hash.h	V_BLOCK		vp->v_block	BLOCK *		../block.h    The V_OCTET is under review and should not be used at this time.    There are a number of macros that may be used to determine    information about the numerical values (ZVALUE, NUMBER and COMPLEX).    you might also want to read the following to understand    some of the numerical types of ZVALUE, NUMBER and COMPLEX:	../zmath.h	../qmath.h	../cmath.h    While we cannot go into full detail here are some cookbook    code for manipulating VALUEs.  For these examples assume    that we will manipulate the return value:	VALUE result;	/* what we will return */    To return NULL:	result.v_type = V_NULL;	return result;    To return a long you need to convert it to a NUMBER:	long variable;	result.v_type = V_NUM;	result.v_num = itoq(variable);		/* see ../qmath.c */	return result;    To return a FULL you need to convert it to a NUMBER:	FULL variable;	result.v_type = V_NUM;	result.v_num = utoq(variable);		/* see ../qmath.c */	return result;    To convert a ZVALUE to a NUMBER*:	ZVALUE variable;	result.v_type = V_NUM;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -