/* ********************************************************************* This source file is a part of the standard library of Scol For the latest info, see http://www.scolring.org Copyright (c) 2013 Stephane Bisaro aka Iri. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ********************************************************************* */ /* * Functions for functions in a package * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file fun.pkg * \author Scol team * \version 0.1 * \copyright GNU Lesser General Public License 2.0 or later * \brief Scol Standard Library - Functions in package API * * \remark The standard packages are required : * - lib/std/stdlib.pkg **/ var PKGS_FUN_SFUN = "fun ";; var PKGS_FUN_SPROTO = "proto ";; var PKGS_FUN_SVAR = "var ";; var PKGS_FUN_STYPEOF = "typeof ";; var PKGS_FUN_STYPEDEF = "typedef ";; var PKGS_FUN_SSTRUCT = "struct ";; var PKGS_FUN_SCOMM = "defcom ";; var PKGS_FUN_SCOMMVAR = "defcomvar ";; var PKGS_FUN_FUN = 0;; var PKGS_FUN_PROTO = 1;; var PKGS_FUN_VAR = 2;; var PKGS_FUN_TYPEOF = 4;; var PKGS_FUN_TYPEDEF = 8;; var PKGS_FUN_STRUCT = 16;; var PKGS_FUN_COMM = 32;; var PKGS_FUN_COMMVAR = 64;; var PKGS_FUN_WHOLENAME = 0;; var PKGS_FUN_PARITALNAME = 1;; var PKGS_FUN_SENSITIVE = 0;; var PKGS_FUN_INSENSITIVE = 1;; fun pkgs_funconvertflags (flag)= if flag == PKGS_FUN_FUN then PKGS_FUN_SFUN else if flag == PKGS_FUN_PROTO then PKGS_FUN_SPROTO else if flag == PKGS_FUN_VAR then PKGS_FUN_SVAR else if flag == PKGS_FUN_TYPEOF then PKGS_FUN_STYPEOF else if flag == PKGS_FUN_TYPEDEF then PKGS_FUN_STYPEDEF else if flag == PKGS_FUN_STRUCT then PKGS_FUN_SSTRUCT else if flag == PKGS_FUN_COMM then PKGS_FUN_SCOMM else if flag == PKGS_FUN_COMMVAR then PKGS_FUN_SCOMMVAR else nil;; fun pkgs_funsetszflags (flag, szFlag)= if flag == PKGS_FUN_FUN then set PKGS_FUN_SFUN = szFlag else if flag == PKGS_FUN_PROTO then set PKGS_FUN_SPROTO = szFlag else if flag == PKGS_FUN_VAR then set PKGS_FUN_SVAR = szFlag else if flag == PKGS_FUN_TYPEOF then set PKGS_FUN_STYPEOF = szFlag else if flag == PKGS_FUN_TYPEDEF then set PKGS_FUN_STYPEDEF = szFlag else if flag == PKGS_FUN_STRUCT then set PKGS_FUN_SSTRUCT = szFlag else if flag == PKGS_FUN_COMM then set PKGS_FUN_SCOMM = szFlag else if flag == PKGS_FUN_COMMVAR then set PKGS_FUN_SCOMMVAR = szFlag else nil;; fun pkgs_funcheckword (pkg, name, pos, isWhole)= if isWhole == PKGS_FUN_WHOLENAME then let nth_char pkg pos-1 -> c1 in let nth_char pkg pos + strlen name -> c2 in if ((c1 == 10) || (c1 == 13) || (c1 == 32)) && ((c2 == 10) || (c2 == 13) || (c2 == 32)) then 1 else 0 else 1;; // partial name, so always true fun pkgs_funsearchinpackage (szPkg, name, isSensitive, isWhole)= let if isSensitive == PKGS_FUN_SENSITIVE then strfind name szPkg 0 else strfindi name szPkg 0 -> pos in if (pos != nil) && (pkgs_funcheckword szPkg name pos isWhole) then if (isWhole == PKGS_FUN_WHOLENAME) && (isSensitive == PKGS_FUN_SENSITIVE) then pos :: nil else pos :: pkgs_funsearchinpackage substr szPkg pos+strlen name strlen szPkg name isSensitive isWhole else nil;; fun pkgs_funsearchfromname2 (list, name, isSensitive, isWhole)= if list == nil then nil else let _getpack _checkpack hd list -> pkg in let pkgs_funsearchinpackage pkg name isSensitive isWhole -> lr in if (isWhole == PKGS_FUN_WHOLENAME) && (isSensitive == PKGS_FUN_SENSITIVE) then [hd list lr] :: nil else [hd list lr] :: pkgs_funsearchfromname2 tl list name isSensitive isWhole;; fun pkgs_funsearchfromname (lPkgs, lFlags, name, isSensitive, isWhole)= let nil -> out in ( while lFlags != nil do let pkgs_funconvertflags hd lFlags -> szFlag in let pkgs_funsearchfromname2 lPkgs strcat szFlag name isSensitive isWhole -> x in if x != nil then ( set out = [hd lFlags x] :: out; if (isWhole == PKGS_FUN_WHOLENAME) && (isSensitive == PKGS_FUN_SENSITIVE) then // Only one element can be found in this case set lFlags = nil else set lFlags = tl lFlags; ) else set lFlags = tl lFlags; out );; /*! \brief Search the definition of a function (or a variable, a type, a Comm ...) * in the current application packages. * * The search is only on the packages loaded in the starting of the * current application. For all loaded packages or the packages * loaded in a given channel, use pkgs_funSearchFromNameChn. For search in loaded package * by a launcher (typically a *.scol), use 'pkgs_funSearchFromNameScol'. * * This is usefull for a programming editor or a debug application. * * \ingroup pkgs_fun * Prototype : fun [S [I r1] I I] [[I [[S [I r1]] r1]] r1] * * \param S : the name to find * \param [I r1] : a list of mode, a mode defines if the searched name * is a function, a variable, etc. The mode can take the following values : * - PKGS_FUN_FUN : a function (fun ...) * - PKGS_FUN_PROTO : a prototype of a function (proto ...) * - PKGS_FUN_VAR : a global variable defined by the keyword "var" * - PKGS_FUN_TYPEOF : a global variable defined by the keyword "typeof" * - PKGS_FUN_TYPEDEF : a type object defined by the keyword "typedef" * - PKGS_FUN_STRUCT : a type object defined by the keyword "struct" * - PKGS_FUN_COMM : a communication (defcom ...) * - PKGS_FUN_COMMVAR : a variable communication (defcomvar ...) * \param I : the search is case-sensitive (PKGS_FUN_SENSITIVE) or case-insensitive (PKGS_FUN_INSENSITIVE) * \param I : the searched name is the whole name (PKGS_FUN_WHOLENAME) or a part of the name (PKGS_FUN_PARITALNAME) * * \return [[I [[S [I r1]] r1]] r1] : a list of results. For each element : * - I : the current mode * - * - [[S [I r1]] r1] : a list with, for each package filename, a list of positions where the name has been found * (this list of positions will be nil if the name is not found in this package). * * \remark If flags are set as PKGS_FUN_SENSITIVE and PKGS_FUN_WHOLENAME, the result should only be one element * \remark Only definitions are returned, not their call or their use in the packages. * \see pkgs_funSearchFromNameChn * \see pkgs_funSearchFromNameScol **/ fun pkgs_funSearchFromName (szFunName, lFlags, isSensitive, isWhole)= let std_starterScriptParse -> [lPkgs _] in pkgs_funsearchfromname lPkgs lFlags szFunName isSensitive isWhole;; /*! \brief Search the definition of a function (or a variable, a type, a Comm ...) * in a given channel. * * The search is only on the packages loaded in a channel. For search in loaded package * by a launcher (typically a *.scol), use 'pkgs_funSearchFromName'. For search in loaded package * by a launcher (typically a *.scol), use 'pkgs_funSearchFromNameScol'. * * This is usefull for a programming editor or a debug application. * * \ingroup pkgs_fun * Prototype : fun [S [I r1] I I] [[I [[S [I r1]] r1]] r1] * * \param S : the name to find * \param [I r1] : a list of mode, a mode defines if the searched name * is a function, a variable, etc. The mode can take the following values : * - PKGS_FUN_FUN : a function (fun ...) * - PKGS_FUN_PROTO : a prototype of a function (proto ...) * - PKGS_FUN_VAR : a global variable defined by the keyword "var" * - PKGS_FUN_TYPEOF : a global variable defined by the keyword "typeof" * - PKGS_FUN_TYPEDEF : a type object defined by the keyword "typedef" * - PKGS_FUN_STRUCT : a type object defined by the keyword "struct" * - PKGS_FUN_COMM : a communication (defcom ...) * - PKGS_FUN_COMMVAR : a variable communication (defcomvar ...) * \param I : the search is case-sensitive (PKGS_FUN_SENSITIVE) or case-insensitive (PKGS_FUN_INSENSITIVE) * \param I : the searched name is the whole name (PKGS_FUN_WHOLENAME) or a part of the name (PKGS_FUN_PARITALNAME) * * \return [[I [[S [I r1]] r1]] r1] : a list of results. For each element : * - I : the current mode * - [[S [I r1]] r1] : a list with, for each package filename, a list of positions where the name has been found * (this list of positions will be nil if the name is not found in this package). * * \remark If flags are set as PKGS_FUN_SENSITIVE and PKGS_FUN_WHOLENAME, the result should only be one element * \remark Only definitions are returned, not their call or their use in the packages. * \remark See also 'scolSearchInChn' (Syspack) http://www.scolring.org/files/doc_html/scolSearchInChn.html * * \see pkgs_funSearchFromName * \see pkgs_funSearchFromNameScol **/ fun pkgs_funSearchFromNameChn (chn, szFunName, lFlags, isSensitive, isWhole)= if chn == nil then nil else let std_getLoadedPackages chn -> lPkgs in pkgs_funsearchfromname lPkgs lFlags szFunName isSensitive isWhole;; /*! \brief Search the definition of a function (or a variable, a type, a Comm ...) * in a given script launcher (typically a *.scol). * * The search is only on the packages loaded by this launcher. * * This is usefull for a programming editor or a debug application. * * \ingroup pkgs_fun * Prototype : fun [S [I r1] I I] [[I [[S [I r1]] r1]] r1] * * \param S : the name to find * \param [I r1] : a list of mode, a mode defines if the searched name * is a function, a variable, etc. The mode can take the following values : * - PKGS_FUN_FUN : a function (fun ...) * - PKGS_FUN_PROTO : a prototype of a function (proto ...) * - PKGS_FUN_VAR : a global variable defined by the keyword "var" * - PKGS_FUN_TYPEOF : a global variable defined by the keyword "typeof" * - PKGS_FUN_TYPEDEF : a type object defined by the keyword "typedef" * - PKGS_FUN_STRUCT : a type object defined by the keyword "struct" * - PKGS_FUN_COMM : a communication (defcom ...) * - PKGS_FUN_COMMVAR : a variable communication (defcomvar ...) * \param I : the search is case-sensitive (PKGS_FUN_SENSITIVE) or case-insensitive (PKGS_FUN_INSENSITIVE) * \param I : the searched name is the whole name (PKGS_FUN_WHOLENAME) or a part of the name (PKGS_FUN_PARITALNAME) * * \return [[I [[S [I r1]] r1]] r1] : a list of results. For each element : * - I : the current mode * - [[S [I r1]] r1] : a list with, for each package filename, a list of positions where the name has been found * (this list of positions will be nil if the name is not found in this package). * * \remark If flags are set as PKGS_FUN_SENSITIVE and PKGS_FUN_WHOLENAME, the result should only be one element * \remark Only definitions are returned, not their call or their use in the packages. * * \see pkgs_funSearchFromName * \see pkgs_funSearchFromNameChn **/ fun pkgs_funSearchFromNameScol (fScol, szFunName, lFlags, isSensitive, isWhole)= let _checkpack fScol -> pScol in if pScol == nil then nil else let std_starterScriptParseP pScol -> [lPkgs _] in pkgs_funsearchfromname lPkgs lFlags szFunName isSensitive isWhole;; /*! \brief Set a flag value string. This is helpfull when the source code * has been written by a different way. Like "fun\nnameOfFunction\n(args)=" * * \ingroup pkgs_fun * Prototype : fun [I S] S * * \param I : a flag (mode), it should be one of these following value * - PKGS_FUN_FUN : a function (fun ...) * - PKGS_FUN_PROTO : a prototype of a function (proto ...) * - PKGS_FUN_VAR : a global variable defined by the keyword "var" * - PKGS_FUN_TYPEOF : a global variable defined by the keyword "typeof" * - PKGS_FUN_TYPEDEF : a type object defined by the keyword "typedef" * - PKGS_FUN_STRUCT : a type object defined by the keyword "struct" * - PKGS_FUN_COMM : a communication (defcom ...) * - PKGS_FUN_COMMVAR : a variable communication (defcomvar ...) * \param S : a string * * \return S : the same string (by example "fun " or "typeof ") **/ fun pkgs_funSetFlag (iFlag, szFlag)= pkgs_funsetszflags iFlag szFlag;; /*! \brief Get a flag value string. * * \ingroup pkgs_fun * Prototype : fun [I] S * * \param I : a flag (mode), it should be one of these following value * - PKGS_FUN_FUN : a function (fun ...) * - PKGS_FUN_PROTO : a prototype of a function (proto ...) * - PKGS_FUN_VAR : a global variable defined by the keyword "var" * - PKGS_FUN_TYPEOF : a global variable defined by the keyword "typeof" * - PKGS_FUN_TYPEDEF : a type object defined by the keyword "typedef" * - PKGS_FUN_STRUCT : a type object defined by the keyword "struct" * - PKGS_FUN_COMM : a communication (defcom ...) * - PKGS_FUN_COMMVAR : a variable communication (defcomvar ...) * * \return S : the string (by example "fun " or "typeof ") * * \see pkgs_funSetFlag **/ fun pkgs_funGetFlag (iFlag)= pkgs_funconvertflags iFlag;; fun pkgs_pkgfunlist (list)= if list == nil then nil else let list -> [name mem nargs prototype next] in [ _CtoScol name mem nargs _CtoScol prototype ] :: pkgs_pkgfunlist next;; /*! \brief Similar to the Scol function "_funlist" but its prototype is easier * * http://www.scolring.org/files/doc_html/_funlist.html * * See also (Syspack) : * * http://www.scolring.org/files/doc_html/funType.html * * http://www.scolring.org/files/doc_html/getInPackage.html * * http://www.scolring.org/files/doc_html/getPackages.html * * http://www.scolring.org/files/doc_html/scolAllFuns.html * * http://www.scolring.org/files/doc_html/scolAllFunsWithArgs.html * * http://www.scolring.org/files/doc_html/scolSearchInChn.html * * http://www.scolring.org/files/doc_html/varType.html * * \ingroup pkgs_fun * Prototype : fun [Chn] [[S I I S] r1] * * \param Chn : any channel * \return [[S I I S] r1] : a list of tuples. For each tuple : * - S : the name of the function (or the variable, ...) * - I : its memory address * - I : the number of arguments (-1 for a variable) * - S : its prototype * \remark At this time, the return is for the last loaded package only. **/ fun pkgs_pkgFunList (chn)= pkgs_pkgfunlist _funlist _envchannel chn;; /*! \brief Returns the source of a function (or other Scol definition objects). * These arguments can be found by the following functions : * * \see pkgs_funSearchFromName * \see pkgs_funSearchFromNameChn * \see pkgs_funSearchFromNameScol * * \ingroup pkgs_fun * Prototype : fun [S I] S * * \param S : a package filename * \param I : a position * \return S : the source or nil if error. **/ fun pkgs_funGetSource (fPkg, pos)= let _checkpack fPkg -> pPkg in if pPkg == nil then nil else let _getpack pPkg -> szPkg in let strfind ";;" szPkg pos -> end in substr szPkg pos end-pos+2;;