Status and Text Reference Coding
Design Notes
Header
From the specifications:
If at all possible, the header containing the definitions for this facility
should be called <status.h> .
Decisions:
Until there is definite evidence of a conflict, the header name will be
<status.h> .
The header should start with a comment naming itself.
That should be followed, after some white space, by a copyright notice.
That should be followed, also after some white space, by the GPL notice and
disclaimer.
That should be followed by a standard idempotentce preprocessor sequence.
The active contents of the header should be within the idempotentce
preprocessor sequence.
Types
From the specifications:
A type, preferably called status_t , should be declared by the
header.
It should be an unsigned integral type assignment compatible with the return
type of the function main .
From the standards:
[extract the appropriate text defining the main interface.]
Decisions:
Until there is definite evidence of a conflict, the type name will be
status_t .
The type will map to unsigned int .
[This is tentative – the unsigned may not be needed.
In fact this may be inappropriate for signed-magnitude integer architectures.]
Note – the actual structure of int varies with the
compiler implementation and machine architecture.
There will eventually be a need for different headers for different
int types.
The most common should be implemented first – 32 bit 2's compliment.
Field order.
From the requirements:
Primary Requirements – phase I
- The results of the project must be usable in 'C' language or 'C'
language derivative programs.
- The status information must indicate whether or not the current result
is usable.
In particular the standard macro
EXIT_SUCCESS must indicate a
usable result and the standard macro EXIT_FAILURE must
indicate an unusable result.
- The status information should also indicate whether or not the current
operation can continue.
In particular the standard macro
EOF must indicate no usable
result and that normal operations can not continue without
intervention.
- Any additional space in the status value should be used to provide
details of what the context of the generated status code was.
This might include which library or program generated the status and a
status category.
- The library or program identifiers should probably be grouped to
indicate the people or company responsible for maintaining the library or
program.
From the specifications:
Access to the various fields in the value must be made using masks.
The size of the fields is as follows:
_RSE_Wcontext >= 10
- This field indicates the context of the status value.
The size of this field is approximate;
an actual survey of open source projects is needed to determine the
acceptable size of this field.
_RSE_Wcontinue == 1
- This field's value indicates if normal operations can continue.
_RSE_Wfacility >= 5
- This field identifies the facility issuing the status value.
If the size of
status_t is 16 bits,
this field will be only 4 bits wide.
_RSE_Wmaintainer >= 10
- This field identifies the maintainer of the facility issuing the status
value.
If the size of
status_t is 16 bits,
this field will be missing; that is its width will be 0.
_RSE_Wresult == 1
- This field's value indicates if the result is usable.
In the following specification, the x must be replaced by one of
the words following _RSE_W in the above list.
For each of the non-zero widths specified, there will also be a value defined
whose name has the form _RSE_Vx that indicates the bit
in the status value corresponding to the least significant bit of the field
value.
This value for zero width fields may be defined but should not be used.
The order of the fields within the status type should be such that a too
large context value automatically increments the
facility field value.
Also, the order of fields within the status type should be such that a too
large facility identifier automatically increments the
maintainer field value if such a field exists.
The maintainer field, if it exists, or the facility
field if the maintainer field does not exist should not overflow
into any higher fields.
For each of the non-zero width fields specified, there will also be a value
defined whose name has the form _RSE_Lx that has a
value equivalent to (1 << RSE_Vx) .
This value for zero width fields may be defined but should not be used.
That is multiplying a desired field value by this number will position that
value correctly for insertion into a status_t value.
For each of the non-zero width fields specified, there will also be a value
defined whose name has the form _RSE_Mx that defines
a mask for isolating the field within the status_t value.
The expression (status & _RSE_Mx) /
_RSE_Lx can be used to get the value of field
x.
This value for zero width fields may be defined as zero, but should not be
used.
If the value of a zero width field is used, the result may be 'undefined
behavior'.
Note: the prefix _RSE_ may have to be changed if it
conflicts with other common usage.
From the standards:
From the POSIX.1 standard for <stdlib.h> :
The <stdlib.h> header shall define the following
macros:
EXIT_FAILURE
- Unsuccessful termination for exit();
evaluates to a non-zero value.
EXIT_SUCCESS
- Successful termination for exit();
evaluates to 0.
From the POSIX.1 standard for <stdio.h> :
The <stdio.h> header shall define the following macros as
positive integer constant expressions:
- ...
The following macro name shall be defined as a negative integer constant
expression:
- EOF
- End-of-file return value.
Decisions:
Until there is definite evidence of a conflict, the field descriptor names
will start with _RSE_ .
Because the common definitions of EXIT_SUCCESS and
EXIT_FAILURE differ only in the least significant bit, the
result field must be the least significant bit.
Because the definition of EOF specifies that its value is
negative, the continue field must be the sign bit.
The order of the context , facility and
maintainer fields is dictated by the overflow requirements.
This means that these fields must abut. .
This also means that the context must be in the least significant
position and that the maintainer must be in the most significant
position.
And finally, this also means that these three field values must be combined
using + rather than | so the overflows propagate
correctly.
Macros
From the specifications:
The following macros may be defined by the user if needed before the header
is included:
RSE_facility
- Sets the facility identifier for the
myStatusDef...
macros.
If not defined, a default value will be set by the
<status.h> header.
RSE_maintainer
- Sets the maintainer identifier for the
myStatusDef...
macros.
If not defined, a default value will be set by the
<status.h> header.
Note: the prefix RSE_ may have to be changed if it
conflicts with other common usage.
Decisions:
Until there is definite evidence of a conflict, these macro names will start
with RSE_ .
Functions or function like macros
From the specifications – part 1:
The following function or function like macros must be defined -
Usable result test indicators:
isBad(status) - true if the
status indicates an unusable result.
isGood(status) - is true if the
status indicates a usable result.
Operation sequence test indicators:
canContinue(status) - is true if the
status indicates the operation sequence can continue.
mustStop(status) - is true if the
status indicates the operation sequence can not continue.
Combined indicator tests:
isDone(status)
- is true if the result is the last value in a sequence of values.
Equivalent to (isGood(status) &&
mustStop(status))
isError(status)
- is true if the status indicates an error condition.
Equivalent to (isBad(status) &&
canContinue(status))
isFatal(status)
- is true if the status indicates a fatal error
condition.
Equivalent to (isBad(status) &&
mustStop(status))
isOverrun(status)
- is true if the status indicates that a sequence nominally
terminated by a
isDone status has been continued.
Equivalent to (isBad(status) &&
mustStop(status))
isSuccess(status)
- is true if the status indicates a normal completion
condition.
Equivalent to (isGood(status) &&
canContinue(status))
isWarning(status) - is true if the
status indicates a warning or alternate completion condition.
Equivalent to (isGood(status) &&
mustStop(status))
It is possible that someone will want to return both a set of indicators and
a count.
The ContextId field is a bit small for this purpose.
It would be better if the size of the value transferred were the same as one of
the standard integer sizes.
The following functions implement the receiving side of such an interface:
isCount(status}
- returns true if the status value contains a count.
statusCount(status)
- returns the count value used to construct the
status value.
The count value returned is a 16 bit signed integer;
that is nominally a
short int .
This function will not be available in environments where
int 's are less than 32 bits wide.
Access to other status components:
statusContextId(status)
- returns the context identifier component of the status
value.
statusFacilityId(status)
- returns the facility identifier component of the status
value.
statusMaintainerId(status)
- returns the software maintainer identifier component of the
status value.
statusMessageId(status) - returns a
message identifier that combines the ContextId and the combined
indicator fields from the status value.
Extensions:
A common practice in the 'C' environment is to return a negative value where
the nominal range of results is positive.
A set of functions to test for these conditions are:
- isCError(int)
- is true if int is negative.
- notCError(int)
- is true if int is not negative,
Another common test is for a NULL return value.
These functions do not depend on the status_t definition but still
make the meaning of the test clearer:
isNULL(pointer)
- is true if the pointer is a NULL pointer.
notNULL(pointer)
- is true if the pointer is not a NULL pointer.
Decisions:
Both functions and macros will be provided for these functions.
From the specifications – part 2:
Status definitions:
statusDef5(good|bad, continue|stop, contextId,
facilityId, maintainerId)
- constructs a status code from all its components.
good|bad is a keyword like argument specifying the value of
the result indicator.
continue|stop is a keyword like argument specifying the value
of the continuation indicator.
statusDef4(success|warning|error|fatal|done|overrun,
contextId, facilityId,
maintainerId)
- constructs a status code from all its components.
success|warning|error|fatal|done|overrun is a keyword like
argument specifying the values of the combined indicators.
statusCountDef3(good|bad, continue|stop,
count)
- constructs a status code that has a combined
contextId and
facilityId that, when extracted by the
statusCount , returns the value of count.
The count value should be in the range of 16 bit signed
integers.
This function will not be available in environments where
int 's are less than 32 bits wide.
statusCountDef2(success|warning|error|fatal|done|overrun,
count)
- constructs a status code that has a combined
contextId and
facilityId that,
when extracted by the statusCount ,
returns the value of count.
The count value should be in the range of 16 bit signed
integers.
myStatusDef3(good|bad, continue|stop,
contextId)
- constructs a status code with preset facility and maintainer identifier
values.
The keyword arguments are the same as for
statusDef5 .
myStatusDef2(success|warning|error|fatal|done|overrun,
contextId)
- constructs a status code with preset facility and maintainer identifier
values.
The keyword argument is the same as for
statusDef4 .
sysStatusDef3(good|bad, continue|stop,
contextId)
- constructs a status code with the system facility and maintainer
identifier values.
The keyword arguments are the same as for
statusDef5 .
The contextId value should be one of the E...
values defined in the <errno.h> system header.
sysStatusDef2(success|warning|error|fatal|done|overrun,
contextId)
- constructs a status code with the system facility and maintainer
identifier values.
The keyword argument is the same as for
statusDef4 .
The contextId value should be one of the E...
values defined in the <errno.h> system header.
Note that specifying an incorrect keyword must produce an error during
compilation, however the relevance of the error description produced by a
compiler is beyond the control of this project and it may not be easy to
comprehend that the message generated is due to a invalid keyword value.
Decisions:
These are to be used, at least in some cases, as static initializers.
That means they must be capable of generating compile time constant
expressions.
That in turn means they must be implemented as macros.
The keyword mapping can be accomplished by taking the macro argument and
prepending (or appending) a reserved character sequence using the preprocessor
operator ## and defining the tokens each of the keywords would
generate.
The sequences to be used here should be _RSE_R for result
keywords,
_RSE_C for continuation keywords and _RSE_S for
combination keywords.
A reasonable set of tokens for keyword abbreviations may also be defined.
Overall suggestions:
- There should be reference implementations that have the compiler perform
as much of the constant calculations as possible.
- There needs to be two reference implementations.
One for small (less than 19 bit integers) and another for larger
integers.
The small integer implementation will be missing several features.
- In the reference models, some field should be designated to grow if more
than the minimum number of bits for the reference implementation are
available.
In particular, the _RSE_Wmaintainer value should grow by half the number of
extra bits,
and the _RSE_Wcode and _RSE_Wfacility values should split the other half
with a slight preference for _RSE_Wfacility.
- The architecture specific implementations should use numeric constants
in place of parenthesized expressions where possible.
(Direct substitutions, like _RSE_Sg for _RSE_Sgood, increase
understandability and maintainability.
They should not be replaced by numeric constants.
However, no more than two levels of indirections should be used.)
References
Note that access to POSIX standards requires a free (as in beer)
registration.
While the 'C' language standard is more fundamental and is referenced by the
POSIX standards,
It is only available for a fee at the present time.
Therefore, references to the more readily available standard are provided.
EXIT_SUCCESS
EXIT_FAILURE
- Both
EXIT_SUCCESS and EXIT_FAILURE are defined
by POSIX.1.
A specific value is only specified for EXIT_SUCCESS .
<stdlib.h>.
EOF
- See POSIX.1
<stdio.h>.
Work List:
- Get the appropriate text that defines the return type of
main .
- Find a citation for the practice of defining
EXIT_FAILURE
as 1.
- Find a citation for the practice of defining
EOF as
-1.
|