mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 10:31:37 -08:00
162 lines
6.7 KiB
ReStructuredText
162 lines
6.7 KiB
ReStructuredText
.. mode: -*- rst -*-
|
|
|
|
The WriteF function
|
|
===================
|
|
|
|
:Tag: design.mps.writef
|
|
:Author: Richard Brooksby
|
|
:Date: 1996-10-18
|
|
:Status: incomplete design
|
|
:Revision: $Id$
|
|
:Copyright: See `Copyright and License`_.
|
|
:Index terms: pair: WriteF function; design
|
|
|
|
|
|
Introduction
|
|
------------
|
|
|
|
_`.intro`: This document describes the ``WriteF()`` function, which
|
|
allows formatted output in a manner similar to ANSI C ``printf``, but
|
|
allows the MPM to operate in a freestanding environment (see
|
|
design.mps.exec-env).
|
|
|
|
_`.background`: The documents design.mps.exec-env and design.mps.lib
|
|
describe the design of the library interface and the reason that it
|
|
exists.
|
|
|
|
|
|
Design
|
|
------
|
|
|
|
_`.no-printf`: There is no dependency on ``printf()``. The MPM only
|
|
depends on ``fputc()`` and ``fputs()``, via the Library Interface
|
|
(design.mps.lib). This makes it much easier to deploy the MPS in a
|
|
freestanding environment. This is achieved by implementing our own
|
|
internal output routines in mpm.c.
|
|
|
|
Our output requirements are few, so the code is short. The only output
|
|
function which should be used in the rest of the MPM is ``WriteF()``,
|
|
which is similar to ``fprintf()``:
|
|
|
|
``Res WriteF(mps_lib_FILE *stream, ...)``
|
|
|
|
``WriteF()`` expects a format string followed by zero or more items to
|
|
insert into the output, followed by another format string, more items,
|
|
and so on, and finally a ``NULL`` format string. For example::
|
|
|
|
WriteF(stream,
|
|
"Hello: $A\n", address,
|
|
"Spong: $U ($S)\n", number, string,
|
|
NULL);
|
|
|
|
This makes ``Describe()`` methods much easier to write. For example, ``BufferDescribe()`` might contain the following code::
|
|
|
|
WriteF(stream,
|
|
"Buffer $P ($U) {\n", (WriteFP)buffer, (WriteFU)buffer->serial,
|
|
" base $A init $A alloc $A limit $A\n",
|
|
(WriteFA)buffer->base, (WriteFA)buffer->ap.init,
|
|
(WriteFA)buffer->ap.alloc, (WriteFA)buffer->ap.limit,
|
|
" Pool $P\n", (WriteFP)buffer->pool,
|
|
" Seg $P\n", (WriteFP)buffer->seg,
|
|
" rank $U\n", (WriteFU)buffer->rank,
|
|
" alignment $W\n", (WriteFW)buffer->alignment,
|
|
" grey $B\n", (WriteFB)buffer->grey,
|
|
" shieldMode $B\n", (WriteFB)buffer->shieldMode,
|
|
" p $P i $U\n", (WriteFP)buffer->p, (WriteFU)buffer->i,
|
|
"} Buffer $P ($U)\n", (WriteFP)buffer, (WriteFU)buffer->serial,
|
|
NULL);
|
|
|
|
_`.types`: For each format ``$X`` that ``WriteF()`` supports, there is a
|
|
type defined in impl.h.mpmtypes ``WriteFX()`` which is the promoted
|
|
version of that type. These are provided both to ensure promotion and
|
|
to avoid any confusion about what type should be used in a cast. It is
|
|
easy to check the casts against the formats to ensure that they
|
|
correspond.
|
|
|
|
_`.types.future`: It is possibly that this type set or similar may be
|
|
used in future in some generalisation of varargs in the MPS.
|
|
|
|
_`.formats`: The formats supported are as follows.
|
|
|
|
======= =========== ================== ======================================
|
|
Code Bame Type Example rendering
|
|
======= =========== ================== ======================================
|
|
``$A`` address ``Addr`` ``000000019EF60010``
|
|
``$P`` pointer ``void *`` ``000000019EF60100``
|
|
``$F`` function ``void *(*)()`` ``0001D69E01000000`` (see `.f`_)
|
|
``$S`` string ``char *`` ``hello``
|
|
``$C`` character ``char`` ``x``
|
|
``$W`` word ``ULongest`` ``0000000000109AE0``
|
|
``$U`` decimal ``ULongest`` ``42``
|
|
``$B`` binary ``ULongest`` ``00000000000000001011011110010001``
|
|
``$$`` dollar -- ``$``
|
|
======= =========== ================== ======================================
|
|
|
|
Note that ``WriteFC`` is an ``int``, because that is the default
|
|
promotion of a ``char`` (see `.types`_).
|
|
|
|
_`.snazzy`: We should resist the temptation to make ``WriteF()`` an
|
|
incredible snazzy output engine. We only need it for ``Describe()``
|
|
methods and assertion messages. At the moment it's a very simple bit
|
|
of code -- let's keep it that way.
|
|
|
|
_`.f`: The ``F`` code is used for function pointers. ISO C forbids casting
|
|
function pointers to other types, so the bytes of their representation are
|
|
written sequentially, and may have a different endianness to other pointers.
|
|
Could be smarter, or even look up function names, but see `.snazzy`_.
|
|
|
|
|
|
Document History
|
|
----------------
|
|
|
|
- 1996-10-18 RB_ Incomplete design.
|
|
|
|
- 2002-06-07 RB_ Converted from MMInfo database design document.
|
|
|
|
- 2013-05-22 GDR_ Converted to reStructuredText.
|
|
|
|
.. _RB: http://www.ravenbrook.com/consultants/rb/
|
|
.. _GDR: http://www.ravenbrook.com/consultants/gdr/
|
|
|
|
|
|
Copyright and License
|
|
---------------------
|
|
|
|
Copyright © 2013-2014 Ravenbrook Limited. All rights reserved.
|
|
<http://www.ravenbrook.com/>. This is an open source license. Contact
|
|
Ravenbrook for commercial licensing options.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
|
|
#. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
#. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
#. Redistributions in any form must be accompanied by information on how
|
|
to obtain complete source code for this software and any
|
|
accompanying software that uses this software. The source code must
|
|
either be included in the distribution or be available for no more than
|
|
the cost of distribution plus a nominal fee, and must be freely
|
|
redistributable under reasonable conditions. For an executable file,
|
|
complete source code means the source code for all modules it contains.
|
|
It does not include source code for modules or files that typically
|
|
accompany the major components of the operating system on which the
|
|
executable file runs.
|
|
|
|
**This software is provided by the copyright holders and contributors
|
|
"as is" and any express or implied warranties, including, but not
|
|
limited to, the implied warranties of merchantability, fitness for a
|
|
particular purpose, or non-infringement, are disclaimed. In no event
|
|
shall the copyright holders and contributors be liable for any direct,
|
|
indirect, incidental, special, exemplary, or consequential damages
|
|
(including, but not limited to, procurement of substitute goods or
|
|
services; loss of use, data, or profits; or business interruption)
|
|
however caused and on any theory of liability, whether in contract,
|
|
strict liability, or tort (including negligence or otherwise) arising in
|
|
any way out of the use of this software, even if advised of the
|
|
possibility of such damage.**
|