Every filesystem has to export its parameters in a format suitable
to user interfaces -- describe name, type, default value, discrete
values, attributes,... of every parameter. This format is not good for
internal usage. Programmer usually wants to access well named
attributes of structure, eg. struct ext2_parameters->block_size
and not to worry about the ranges,...
To make coding fs-parameters easier, M4 macros gener_params.m4
is used. Programmer describes fs-parameters in params.m4
file
and the macroprocessor generates params.h
file (with C-structure
declaration, declaration of conversion functions and #define
s of
parameter numbers) and params.c
file (with array of parameter
descriptions and conversion function definitions). After this is done,
you can easily use the structure for your own and call conversion
function if you want to communicate with user interface.
The params.m4
file looks like:
include(gener_params.m4)dnl define(PREFIX_,SWAP_PAR_)dnl add_attribute(header,Header version,int #,import()export()detect() discrete_string(swap_headers,0)) add_attribute(endian,Machine CPU endianity,int #,import()export()detect() discrete_string(swap_endianities,0)) add_attribute(pagesize,Machine CPU page size,int #,import()export()detect() discrete_string(swap_pagesizes,0)) '
You can ignore the 1st line beginning with dnl
, it's just a comment.
The 2nd line includes macro file. The 3rd line is very important, it defines
prefix used for parameter names -- parameter header
will be
accessed as SWAP_PAR_HEADER
in this example (suffix is the uppercased
parameter name). Every other line contains declaration of one parameter.
Macro add_attribute
gets these parameters:
add_attribute
has only 3 parameters),
it will be automatically substituted by the same string as in the previous
name parameter, although such substitution is not wised due to worse user
friendliness. This 3-par compatibility kludge may be removed in future versions.
Any localization from gettext PO file
will apply to the value given in
this parameter, either specified directly or by the mentioned substitution.gener_params.m4
needs to get a lot of information in just one
parameter, so some macros are called and concatenation of their results
is puted into 3rd parameter.
You describe the parameter flags at first. Just list the flags you want the parameter to have and enclose them in `'. You can use these flags: import(), export(), detect(), determ().
After this string you must append the parameter type -- a special macro is defined for every possible parameter type. You describe the ranges, descrite values, default values,... as the parameters of this macro.
There are these possible parameter types:
There are also some flags which can modify the generated code. You will not need them in normal case as they are useful for parsing and assembling of parameter arrays from several defined tables. They can be used as in the following example:
dnl All disk parameters are shared => ignore unknown ones define(ignore_invalid_param,1) dnl We need all "struct disk_info" parameter to not to clash each other: define(keep_last_define,1)
In default case the generated code will always
generate error message (to given ERR_PASS) when it will find any parameter
in the given array which it doesn't understand. You don't want this default
behaviour (and so you want to enable this flag) if the same array will be
parsed by several different parsers (struct_array
functions).
In default case all generated parameter IDs start from number 1. If several tables for the same parameter array are defined, you need to ensure that they are all using different ID numbers. This flag will do it for you.
The last thing you have to do is write params.c.m4
and
params.h.m4
sources. Look at some existing filesystem for details,
you must writes some things that are not directly connected to
fs-parameters there (#include
s, definition of discrete value
arrays,...). Than write `include(params.m4)
' and make the macros
print generated code by calling `FS_declare_all(`swap')
' in
params.h.m4
or `FS_define_all(`swap',`SFSW',`Linux swap')
'
in params.c.m4
. The first parameter `swap' is prefix used
for generated conversion functions, `SFSW' is prefix for error
messages and `Linux swap' is a name of the filesystem.
In addition to the previously noted functions FS_declare_all()
and FS_define_all()
you can also use their
FS_declare_read_only()
and FS_define_read_only()
variants,
respectively. By using this read_only
variant you'll create
only struct_array_#_pars
and struct_array_#_pars_keep
function,
otherwise even array_struct_#_pars
and #_getparlist
would be created:
(present in both the "all" and "read_only" variants)
This function will read the parameters given in struct user_parameter
array
(of size count
), you'll use this function in any C code dealing with user parameters.
Any parameters which are missing in input a
array are automatically reset
to its default value as declared in your params.m4
file. This function will
always rewrite all the fields of input-only structure s
parameter.
(present in both the "all" and "read_only" variants)
This function has identical functionality as struct_array_#_pars_init
function
described above with one exception: Any parameters missing in input a
array
are left their original value (as passed in input/output s
parameter).
Use this function if you want to subsequently read several input user_parameter
arrays (passed each separately during the calls in a
parameter). This function
is rarely used.
(present only in "all" variant)
This function will write the parameters to the given struct user_parameter
array
(of size count
). Function is probably needed only by filesystem implementations.
(present only in "all" variant)
This function will fill in the given struct fs_pars
by copying the static
definition of default values. Additionally fp_type
, fp_name
and fp_count
fields are also initialized.
Function is needed only by filesystem implementations.
Functions array_struct
/struct_array
will produce debug output
with VERBOSE
level for each parameter copied. If you are aware during their
use that you are using due to some reason these functions multiple times
and such output would be disturbing log files, you can pass the count
parameter as negative (-count
value instead). Negative value will have
the function effect as ABS(count)
but no debugging output will be generated.
Such debugging output (and this feature at all) has no effect on final
Surprise package releases for users, of course.
That's almost all. Add
include $(top_srcdir)/src/Makefile.params
line into your Makefile.am
and add params.c
into the SOURCES list.
Please not that files params.m4
with params.[ch].m4
don't need to be
specified in EXTRA_DIST by you, it is done automatically by included
Makefile.params
. make
will automatically generate params.[ch]
from params.[ch].m4
, all usuall functions will be declared and defined --
look at some existing filesystem for details.