/* *********************************************************************
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;;