Symple MenuCfg script format
----------------------------
MenuCfg is script with 'standard' syntax based on 'sections' which can be included in files
with c/cpp/h/cfg/asm extensions.
SECTIONS
========
Scripts related to MenuCfg scripts have to be enclosed between
#make_config_begin [execution_level_number]
#make_config_end
If script is present in c/cpp/h files, it should be also within #if 0 & #endif pair, to tell
preprocessor to exclude this part.
Every section is enclosed between
#section_name
#end
Sections can't be nested. Every file can contains more sections and more #make_config_* if
required. Every file have 'execution' priority. Exist few section which are executed by MenuCfg
itselfs. Running priority means: if there is request to run section "XXX" and there is more
files with this section, they will be runned at order according to priority. Priority comes
from 0 [higest - don't use] to 9 [lovest]. 4 is normal (if not given, 4 is used).
Section runned by MenuCfg:
#init
- executed globally when all files are searched for scripts
- foor time for create menus, config files, ...
- at this time SCIPT (macros) NOT YET READY FOR USING !
#prepare
- like init, but macros are ready for using (coz #init have to register them)
#dependencies
- every time any menu item is changed
- executed globally
- used for cheking dependencies (for ex. you have checkbox X and where is is checked,
user can't enter menu YYY. In this case, you will add #dependencies section
and disable menu YYY if item X is selected -> like:
#dependencies
item_gray(manuAliasForYYY,item_val(menuAlias,SOME_MENU_VALUE))
#end
You can ofcourse use if/else/fi pair.
#enter
- when user request to enter MENU.
- menu alias stored to variable _current_menu (see special variables)
- executed locally (only for menu OWNER)
#leave
- leaving menu
- _current_menu hold menu which is being to leave
- executed locally (only for menu OWNER)
SYNTAX
======
MakeCfg doesn't use any line separator. It ignores blank spaces (like empty lines). Everything
is CaSe SeNsItIvE. If you need to use parameter with spaces or special characters (+-,....) you
need to enclose given string to ". There is no difference between passing value "value" or
value. It have few rescritions:
1. function parametres where is expected variable name, " can't be used
2. variable names can't be enclosed to "
3. identifiers (such as function names, aliases, ...) can use only these characters:
a-z A-Z _ . 0-9 and ofcourse, using " is not allowed.
Every line starting with # at non-blank character is takes as directive. Nowdays is defined
section enclosing (see above) directives.
Comments - only EOL comments are supported - // this is a comment
MenuCfg have many internal functions. Deffining own is not allowed. You can define ulimited
number of sections, and scripts (macros). Some function return boolean value and can be used
with if/while commands. Function have standard form: FunctionName(parameter1,parameter2,...)
VARIABLES
---------
MenuCfg knows variables. Variable is referenced by $name. Every variable is ARRAY of TEXT.
Variables which uses only first index of array are also called 'symple'. Separator for values
is char '\n'. So, if you will asign to variable "aaa\nbbb" you assign "aaa" to element 0 of
array and "bbb" to element 1. Writing $variable you are saying "use first element".
Note: string contsants support "C" string convention:
\\ -> \
\n -> enter mark
\" -> "
\' -> '
Variables care created at first time reference, and holds for the remainder of running time.
Variables working:
1. Assign
$variable=value where value cab be:
a. different variable $var1=$var2
b. text constant $var="something" or $var=something
c. combination $var=$var_2+"string with spaces"+non_spaces_string
2. Appending - appends to firat array item. Strip other aray elements
$variable+=what_to_add
3. Adding - adds to end of array new line
$variable^=new_item
Examples:
$a="Line1"
$a+=xxx // Line1 is now Line1xxx
$a^=Line2 // Line1 is now Line1xxx\nLine2
$b=__b__
$c+=$b // c is now Line1xxx__b__
$c+=b // c is now Line1xxx__b__b
We have function fn(string value,variable dst)
fn(test,$b) // WRONG ! second parameter is required to be "b" - we're passign VARIABLE not VALUE
fn("test",b) // right
fn($a,b) // right
fn($a+$b+"something to add",c) // right
Some functions required to pass variable, because it fills uses more array elements - like scanning
files, or user selection.....
If you're sure variable exists, you don't need to create it be hand. Also, don't forget variables
exists from creation time to exit, so, enough is to create vars a #init or some another section.
Exists 2 variable types:
1. local - $variable (accesible only in current #make_config_* pair)
2. global - accesible from anywhere - name of variable need to start with '_' e.g. $_shared
Exists some internal variables (written l8r)
Aliases
=======
Alias is special name (which have to start with alpha and can contains only alphas & number
and _) which allows you to recognize more elements. Aliases are local, till you will use
function "share". Normally, is alias passed as normally (by its name). But if you want to
access alias from different config, you have to use '.' override in form:
shared_name.alias_name
Let's say we have script which uses somewhere alias "MainMenu" and it uses share(mine_test). So,
for adding item to menu we will pass to menu function alias "mine_test.MainMenu".
If no shared is given (so, single alias is given), current file is used (what another ?)
You're allowed to access "own" aliases by yours share name (this_file_share_name.alias). But
there is not reason why do it.
Scripting
=========
Scripts are verry usefull. "Idea" of menucfg is to make adding files easi as posible. Because
of macros, it is possible. This is example from real live:
// ~!Script_application("Source manager", \
// APP_SOURCE_MAN, \
// Files_SourceMan, \
// 0x18D08EE269DC6CFE) \
This is all to add file to menu, server creators etc. Ofcourse, it is beacause of that script
(this is anyway from FC related MenCfg thigs).
As you can see, macro is called by "// ~!Smacro_name(params)". Params can be splitted to more
lines (see above). Macro is requied to be registered (#init section) with register_script
fuction (see down). After init, it can be used. Is recomended to use "Macro_" or "Script_"
at start of the name.
Macros need to be included BEFORE #make_config_end, but withing special tags:
#$Scripts // this tag haven't "end" - fro mthis point to the end of cfg are scripts
#make_config_end
Macros itselfs is defined by form:
#$Name_of_macro
#$end
Macro body can use mroe section (at least one). It is full 'stand alone' script. Parametres
(count passed by function) are referenced by $!x! where x is decimal number. Parametres are
numbered from 0.
Example - this example adds file, where this macro is used to makefile, but only
if given paltform is selected:
//-------------------------------------------------------------------------
// basic FC base components script - platform dependent
// params: valid platform (OS) name
//-------------------------------------------------------------------------
#$Script_FcBase_platform
#build_fc_base_cache_create
if item_val(FC.DEST_OS,$!0!) then
cache_file_add(Build.Cache,$_current_file_full)
fi
#end
#$end
FC.DEST_OS says: "FC" shared name, "DEST_OS" alias (FC uses aliass for end items in upper case)
And using ?
Like FcWin.cpp:
// ~!Script_FcBase_platform("OS_WIN_*")
Macros can start with '//' or ';' initially. If continue on next line, initial // or ; is ignored
(for compatibility with language).
Scripts can be also called FROM script. Call is done by form "$!Script_Name(parametres)". Scripts
can be invokes as whole sections defining new scripts :) Example:
Somewhere:
// generaes error if given OS is not selected
// Params: 0 - item
// 1 - required OS
// 2 - error
// 3 - build section name
#$Script_Core_TestOS
#build_$!3!_dependencies
if item_val(Build.$!0!,true) then
if !item_val(FC.DEST_OS,$!1!) then
log_error($!2!)
fi
fi
#end
#$end
We want to use this script (we also have Register_Script in our initialization):
// Script_Application_Test_OS - logs error if given OS is NOT selected
// Params: 0 - Item name
// 1 - Required os
// 2 - Error
#$Script_Application_Test_OS
$!Script_Core_TestOS($!0!,$!1!,$!2!,apps)
#$end
Scripts are created at call-time, while #init section is called.
COMMANDS
========
-=> for Var in [list] do .... done
Sets Var to every part of given list and executes comands between do-done. Ends
on last list position (so, cycle is executed INCLUDING last given value).
List form:
1. variable - Var is sets to every values of given variable (if it is
array ofcourse)
2, [item1,item2,item3] - comma delimited item format, where item can be
physical value or range in form "start-end". Only
numeric values are allowed as range parameter
-=> if (expression) then ... else ... fi
If expression is TRUE function executed commans after do. If FALSE, and else block
is presents, it is executed. Else block can be not used. In this case, only
'if ... fi' is presents.
Expression can use function which return values and combinations of following operators:
(....) - standard math ()
&& - and
|| - or
== - equal (variables only)
!= - not equal (variables only)
! - make negative of following operand
-=> while (expression) do .... done
While expression is TRUE, function executes commands. See 'if' for details.
SPECIAL VARIABLES
=================
-=> _msg_wnd_key
holds key which last message were canceled (functions message_window*)
-=> _current_menu
entering menu alias
-=> _current_file_path
file path where current script is running - related to root of MenuCfg
-=> _current_file_full
full fle path....
-=> _running_cpu
-=> _running_compiler
-=> _running_os
current OS/Compiler/CPU name - for example:
Intel Pentium MMX | Intel Pentium II | Intel Pentium III
WATCOM 10.5 | Microsoft C++ 6.00
Microsoft Windows NT 4 | Microsoft Windows 95/98
note: returned string should contains string by which can scritps get version well
(like if it is "windows" be search "windows" string, and if yes, search "NT"
will say details, ....)
-=> _FC_ID
generates new FireComponent ID. Every time another. in form 0x123456789abcdef
-=>_time_stamp
retuns time stamp in form "Thu Jul 27 15:43:31 2000"
VARIABLES
=========
-=> get_max_index(variable Src,variable Dst)
Wrties maximal index of given array in Src variable. To Dst variable is written
decimal string (e.g. "156"). If string variable is not array, return value is 1.
If variable is empty, return value is zero.
-=> add(variable Var,string Value)
-=> sub(variable Var,string Value)
Adds or substract given Value from variable. If Value is not numericall, error
is generated. If Var is empty or non-numerical value, zero is assumed (so, output
is 0+Value or 0-Value). Result is again numerical. Negative numbers are not supported.
-=> bool str_str(string String,string SubString)
Return TRUE of String contains given SubString. Otehrwise FALSE. Case insensitive.
-=> bool str_equ(string StrA,string StrB,string Length)
Compare Length characters of StrA and StrB. If they're same, returns TRUE. Otehrwise
false. If Length is 0, wholse string is tested. Case sensitive.
-=> bool str_equr(string StrA,string StrB,string Length)
The same like 'str_equ' but works from RIGHT side.
-=> str_copyl(variable Dst,variable Src,string Length)
Copy Length characters from Src to Dst. If Length is zero, whole string is copyied.
-=> str_copyr(variable Dst,variable Src,string Length)
The same like 'str_copyl' but works from RIGHT side.
-=> str_copyfrom(variable Dst,variable Src,string Pos)
Copy characters from Src starrting at position Pos to Dst.
-=> str_remove_ext(string Source,variable Dst)
Cuts Source string at first '.' character from right. Result moved to Dst variable.
-=> str_remove_ext_spec(string Source,variable Dst,string ExtChar)
Same as previous, but extension char is user defined.
-=> str_get_ext(string Source,variable Dst)
Get source string after last '.'. Result moved to Dst variable.
-=> str_get_ext_spec(string Source,variable Dst,string ExtChar)
Same as previous, but extension char is user defined.
-=> bool str_get_group(string Source,string Index,variable Dst)
Find Index-th comma divided part from Source and copy to Dst. If given part is not
found, FALSE is returned.
Example: $line="var,val1,val2,val3"
$res=""
str_get_group($line,2,res)
will return TRUE and res will contain "val2"
-=> bool str_get_group_spec(string Source,string Index,variable Dst,string Separator)
Same as previous, but separator is user-defined.
GENERAL
=======
-=> exec(string SectionToExec)
Executes given section named SectionToExec, only in current file (locally)
-=> exec_global(string SectionToExec)
Executes all sections named SectionToExec in ALL files
-=> log_error(string Text)
-=> log_warning(string Text)
Logs error or warnign. Logs are visible to user (only when not empty). Text shouldn't
contains \n character. For user is visible "Warning: text" or "Error: text"
-=> share(string Alias)
Enabled sharing local aliases (such as items, config files, ...) by other files, using
given Alias. Use this command at #init time.
-=> exit
Exists current section.
-=> break
Breaks current loop (if/while/...). If used without loop, error is generated.
USER INPUT/OUTPUT
=================
-=> message_window(string Text,string PossibleReturns)
-=> message_window_error(string Text,string PossibleReturns)
-=> message_window_fatal(string Text,string PossibleReturns)
Shows window which looks like normal/error/fatal meesage. String PossibleReturns
consist of keys by which message can be canceled. If this string is "no wait",
every pressed key will work. Result is stored to variable _msg_wnd_key
-=> make_dep(string SourceFile,variable Destiantion)
Scan given file for #include preprosessor commands. Scanned files are also processed
recursivelly. Ouptut is string array, where each record is file path to included file
with extension. Files above root (dir where MakeCfg were runned) are ignored.
-=> bool get(variable Dst,variable Src,string Index)
Fills Dst variable with Index-th string of Src variable. If Src is not array, or Index
is out of bounds, Dst is filled with empty string, and FALSE is returned. If all is
sucessfull, TRUE is returned.
Example: $vals="one\ntwo\trheee"
$x=""
get(x,vals,1);
x will retrieve "two" and function will return TRUE.
-=> bool locate(variable Src,string String)
Query variable if contatins 'String'. If yes, return value is TRUE.
-=> bool get_text(variable Var,string Name,string MaxLen)
Gets string from user. Maximal length of MaxLen characters. At start is displayed
"original" contents of Var. If user press enter, function fill Var with entered text
and return TRUE. Otehrwise FALSE. Name is written before first line of entered text.
Size is not limited by X screen size. Inputting window is automaticly sized to best
fit MaxLen. It is limited by ((screen size Y-4) /2) lines.
-=> bool get_option(variable ValuesList,variable Dst)
Shows to user selection from givem list of values. If user selects, functions fill
Dst with selected value and return TRUE. Otherwise FALSE. ValuesList array need to
include at leats one line.
-=> menu_create(string MenuAlias)
Creates menu with given Alias. Use given alias for access menu items. If given menu
allraedy exists, function fails.
-=> abort_menu()
Aborts current menu, use only at #enter menu handler.
ITEMS
=====
Items are part of menus/selections. For access them you need to know alias of them. Every add
is added to end of current list. Aliases need to be unique. Differnece between captions and
aliasses is symple: Caption can contaion any characer, Alias only identifier allowed.
Items are used to manage MENUS.
-=> items_add_list(string MenuAlias,string ItemListAlias,string Caption)
Adds 'list' to menu. Item list need exists at adding time. Use 'list_add' for adding
items to list.
-=> items_add_submenu(string MenuDstAlias,string MenuToAddAlias,string ItemAlias,string Caption)
Adds submenu to menu. Submenu in this menu is accesible by ItemAlias alias.
-=> items_add_check(string MenuAlias,string ItemAlias,string Caption)
Adds check box to menu. you will retreive TRUE/FALSE by query this menu item.
-=> items_add_edit(string MenuAlias,string ItemAlias,string Caption)
Adds edit to menu.
-=> items_add_button(string MenuAlias,string ItemAlias,string Caption)
Adds button to menu. When user cick on button, section "button_[ItemAlias]" is executed
(locally).
-=> list_add(string ListAlias,string ValueAlias,string Caption)
Adds item to item list. If ListAlias doesn't exist or ValueAlias exists, function
fails.
-=> item_gray(string ItemAlias,string BoolValue)
If BoolValue is true, item is graied (can't be selected)
-=> item_val_set(string ItemAlias,string Value)
Sets ItemAloas value to Value. If Item is:
1. list
Value need to be valid part of list
2. check
Value need to be "true" or "false"
3. Edit
Value is not limited
To other item types (menu, ...) can't be assigned value.
-=> item_val_get(string ItemAlias,variable Dst)
Gets value of item. See 'item_val_set' for details.
-=> item_caption_get(string ItemAlias,string NewCaption)
Retrived caption of given item. For "List" items is caption current value. For
"Edit" it is current "value". For others, it is "Name" (showed to user)
-=> bool item_val(string ItemAlias,string ValToTest)
Test value of item. ValTotest can contain '*'. See 'item_val_set' for more
informations.
Example of menu:
#prepare
menu_create(menuMain)
menu_create(menuAddons)
// create submenu
items_add_check(menuAddons,optFormat,"Format HDD")
items_add_edit(menuAddons,optNewLabel,"Label after formatting") // this should be grayed when format not selected :)
// create main menu
items_add_submenu(menuMain,menuAddons,menuMain_Addons,"Formatting options")
items_add_check(menuAddons.....
.
.
.
#end
INPUT/OUTPUT
============
-=> io_validate_fname(var Var)
Validate string in Var to be valid MenuCfg path (so, it uses "/" and can't contain
space).
-=> io_validate_fname_sys(var Var)
Validate string in Var to be valid SYSTEM path. It depends on targer platform. For ex.
in Windows it will contain "\". Usefull for generating system batch files, or makefiles.
MenuCfg internally not uses system paths.
-=> io_divide_path(string FullFile,variable Path,variable File)
Divides fiven FullFile to path and file_name and writes to corespoding given vriables.
-=> bool io_mkdir(string DirToMake)
Makes directory in given folder (eg. SomeDir/newDir - SomeDir have to exists). If you
need to create more complex structures, you need to call io_mkdir more times.
-=> void io_test(string Path,variable Dst)
Test given path/directory and return type. Known types:
"D" - directory
"F" - file
"" - doesn't exists
-=> io_scan_dir(string Path,string Mask,variable Dst)
Scan dirs recursivelly from Path and if any file match given Mask, adds it to
Dst variable. Paths are from MenuCfg root.
-=> bool io_get_env(string name,var Dst)
Sets Dst to enviromane variable 'name'. If variable exists, and it is NON-EMPTY,
return value is TRUE else FALSE.
MISC
====
-=> make_dependence(string SourceFile,variable Dst,string IncludeCommand)
Makes file dependence list from givem filename. It matches every 'IncludeCommand' where
is expected file (can be enclosed in " or '). Tifle is added to Dst and process
in recurse. Include command for C/C++ file is "#include"
CONFIG FILE
===========
Config file is text based file, where can be stored anything. It can be C/C++/Asm/... source,
makefile, whatever. CF are based on aliases. Before using, you need to create CF and then use
given alias for all CF related functions. Every operation is done withing CF cache. For access
real file you need to use read/write functions.
-=> cf_create(string Alias)
Create CF named Alias. Use this alias for other CFs. You don't need to destroy CF. If
given CF allready exists, function fail.
-=> bool cf_read(string Alias,string File)
Reads file for CF cache. From this point, you can work with file contents. If file
is found, and readed, function returns TRUE. If file is not found, returns FALSE.
If error occururs diring reading, it generates error (so, you don't need to handle)
-=> cf_write(string Alias,string File)
Reverse function for 'cf_read'. Storec CF cache to given file. If error occurs during
read, function generates error.
-=> bool cf_line_locate(string Alias,string TextToLocate)
Tries to find TextToLocate in given config file. '*' can be used (eg. "Value,*" will
find everything starts "Value,"). If given line si founded, function return TRUE.
-=> bool cf_line_locate_get(string Alias,string TextToLocate,variable Dst)
The same like 'cf_line_locate' but also stored founded line (always full, not care
if * is used or not)
-=> bool cf_line_get(string Aias,string LineIndex,variable Dst)
Stores LineIndex-th line from config file for Dst variable. If line exists, function
return TRUE. If not exists, return FALSE and fills Dst with empty string.
-=> cf_empty(string Alias)
Empty CF cache (-> not delete or erase contents file).
-=> cf_line(string Alias,string Line)
Puts Line to CF. Add end mark (cr/lf - depends on target os).
-=> cf_section(string Alias,string SectionName)
Adds whole section from current file to config file. Section is enclosed to
##section_name pair. It should be not INSIDE normal #block (after execution this block
syntax error will occurs)
-=> cf_string(string Alias,string CharsToAdd)
Puts CharsToAdd to CF doesn't put new line mark.
CACHE
=====
Cache is special file, where are storred settings. It is 'comma' delimited format. These
function works with CF cache. Use with comnination of other CF functions. These function
help while generating makefiles/servers, where script parses CF line per line and produce
right action (for ex. on "option" ignore line, on "file" add file to makefiles, ...)
-=> cache_option_write(string Alias,string ItemAlias)
Write to cache line in form: "option,ItemAlias,ItemValue". ItemValue is obtained
by call item_val_get.
-=> bool cache_option_read(string Alias,string ItemAlias,string DefaultValue)
Search cache by line "option,ItemAlias,*". If found, sets ItemAlias to value
from cache and return TRUE. Otherwise sets ItemAlias value to DefaultValue
and returns FALSE.
-=> cache_file_add(string Alias,string FileName)
Adds to CF line in form "file,FileName".
-=> cache_comp_add(string Alias,string StaticCreator,sting ID)
Adds to CF line in form "component,StaticCreator,ID"
-=> bool cache_file_locate(string Alias,string FileToLocate)
Returns TRUE if given CF contatins line "file,FileToLocate".
SCRIPTS
=======
-=> register_script(string ScriptAlias,string ParametresCount)
Register script. Script have to be included in current file. See Scripting for details.