xref: /plan9/sys/src/cmd/gs/doc/C-style.htm (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
13ff48bf5SDavid du Colombier<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
27dd7cddfSDavid du Colombier<html>
37dd7cddfSDavid du Colombier<head>
43ff48bf5SDavid du Colombier<title>Ghostscript C coding guidelines</title>
5*593dc095SDavid du Colombier<!-- $Id: C-style.htm,v 1.55 2005/10/20 19:46:23 ray Exp $ -->
67dd7cddfSDavid du Colombier<!-- Originally: c-style.txt -->
73ff48bf5SDavid du Colombier<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style">
87dd7cddfSDavid du Colombier</head>
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier<body>
117dd7cddfSDavid du Colombier<!-- [1.0 begin visible header] ============================================ -->
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier<!-- [1.1 begin headline] ================================================== -->
147dd7cddfSDavid du Colombier
153ff48bf5SDavid du Colombier<h1>Ghostscript C coding guidelines</h1>
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier<!-- [1.1 end headline] ==================================================== -->
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier<!-- [1.2 begin table of contents] ========================================= -->
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier<h2>Table of contents</h2>
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier<blockquote><ul>
247dd7cddfSDavid du Colombier<li><a href="#Introduction">Introduction</a>
253ff48bf5SDavid du Colombier<li><a href="#C_language">C language do's and don'ts</a>
267dd7cddfSDavid du Colombier<ul>
273ff48bf5SDavid du Colombier<li>Preprocessor:
283ff48bf5SDavid du Colombier    <a href="#Conditionals">Conditionals</a>,
293ff48bf5SDavid du Colombier    <a href="#Macros">Macros</a>,
303ff48bf5SDavid du Colombier    <a href="#Preprocessor_other">Other</a>
313ff48bf5SDavid du Colombier<li><a href="#Lexical_elements">Lexical elements</a>
323ff48bf5SDavid du Colombier<li><a href="#Scoping">Scoping</a>
333ff48bf5SDavid du Colombier<li>Data types:
343ff48bf5SDavid du Colombier    <a href="#Scalars">Scalars</a>,
353ff48bf5SDavid du Colombier    <a href="#Arrays">Arrays</a>,
363ff48bf5SDavid du Colombier    <a href="#Typedefs">Typedefs</a>,
373ff48bf5SDavid du Colombier    <a href="#Structures">Structures</a>,
383ff48bf5SDavid du Colombier    <a href="#Unions">Unions</a>
393ff48bf5SDavid du Colombier<li><a href="#Expressions">Expressions</a>
403ff48bf5SDavid du Colombier<li><a href="#Statements">Statements</a>
413ff48bf5SDavid du Colombier<li><a href="#Procedures">Procedures</a> (prototypes and definitions)
423ff48bf5SDavid du Colombier<li><a href="#Standard_library">Standard library</a>
433ff48bf5SDavid du Colombier</ul>
443ff48bf5SDavid du Colombier<li><a href="#Language_extensions">Language extensions</a>
453ff48bf5SDavid du Colombier<li><a href="#Stylistic_conventions">Stylistic conventions</a>
467dd7cddfSDavid du Colombier<ul>
473ff48bf5SDavid du Colombier<li>Formatting:
483ff48bf5SDavid du Colombier    <a href="#Indentation">Indentation</a>,
493ff48bf5SDavid du Colombier    <a href="#Spaces">Spaces</a>,
503ff48bf5SDavid du Colombier    <a href="#Parentheses">Parentheses</a>
513ff48bf5SDavid du Colombier<li><a href="#Preprocessor_style">Preprocessor</a>
523ff48bf5SDavid du Colombier<li><a href="#Naming">Naming</a>
533ff48bf5SDavid du Colombier<li><a href="#Types">Types</a>
543ff48bf5SDavid du Colombier<li><a href="#Procedures_style">Procedures</a>,
553ff48bf5SDavid du Colombier<li>Miscellany:
563ff48bf5SDavid du Colombier    <a href="#Local_variables">Local variables</a>,
573ff48bf5SDavid du Colombier    <a href="#Compiler_warnings">Compiler warnings</a>
587dd7cddfSDavid du Colombier</ul>
593ff48bf5SDavid du Colombier<li><a href="#File_structuring">File structuring and naming</a>
607dd7cddfSDavid du Colombier<ul>
617dd7cddfSDavid du Colombier<li><a href="#All_files">All files</a>
627dd7cddfSDavid du Colombier<li><a href="#Makefiles">Makefiles</a>
633ff48bf5SDavid du Colombier<li><a href="#General_C_code">General C Code</a>
647dd7cddfSDavid du Colombier<li><a href="#Headers">Headers (<b><tt>.h</tt></b> files)</a>
653ff48bf5SDavid du Colombier<li><a href="#Source">Source (<b><tt>.c</tt></b> files)</a>
667dd7cddfSDavid du Colombier</ul>
673ff48bf5SDavid du Colombier<li><a href="#Conventions">Ghostscript conventions</a>
687dd7cddfSDavid du Colombier<ul>
693ff48bf5SDavid du Colombier<li><a href="#Specific_names">Specific names</a>:
703ff48bf5SDavid du Colombier    <a href="#code"><b><tt>code</tt></b></a>,
713ff48bf5SDavid du Colombier    <a href="#status"><b><tt>status</tt></b></a>
723ff48bf5SDavid du Colombier<li><a href="#Structure_type_descriptors">Structure type descriptors</a>
733ff48bf5SDavid du Colombier<li><a href="#Objects">"Objects"</a>
747dd7cddfSDavid du Colombier<li><a href="#Error_handling">Error handling</a>
757dd7cddfSDavid du Colombier</ul>
767dd7cddfSDavid du Colombier</ul></blockquote>
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier<!-- [1.2 end table of contents] =========================================== -->
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier<!-- [1.3 begin hint] ====================================================== -->
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier<p>
837dd7cddfSDavid du ColombierFor other information, see the <a href="Readme.htm">Ghostscript
847dd7cddfSDavid du Colombieroverview</a>.
857dd7cddfSDavid du Colombier
867dd7cddfSDavid du Colombier<!-- [1.3 end hint] ======================================================== -->
877dd7cddfSDavid du Colombier
887dd7cddfSDavid du Colombier<hr>
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier<!-- [1.0 end visible header] ============================================== -->
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier<!-- [2.0 begin contents] ================================================== -->
937dd7cddfSDavid du Colombier
943ff48bf5SDavid du Colombier<h2><a name="Introduction"></a>Introduction</h2>
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier<p>
973ff48bf5SDavid du ColombierThis document describes Ghostscript's C coding conventions.  It is primarily
983ff48bf5SDavid du Colombier<em>prescriptive</em>, documenting what developers should do when writing
993ff48bf5SDavid du Colombiernew code; the companion developer documentation (<a
1003ff48bf5SDavid du Colombier href="Develop.htm">Develop.htm</a>) is primarily <em>descriptive</em>,
1013ff48bf5SDavid du Colombierdocumenting the way things are.
1027dd7cddfSDavid du Colombier
1033ff48bf5SDavid du Colombier<p>
1043ff48bf5SDavid du ColombierWe encourage following the general language usage and stylistic rules for
1053ff48bf5SDavid du Colombierany code that will be integrated with Ghostscript, even if the code doesn't
1063ff48bf5SDavid du Colombieruse Ghostscript's run-time facilities or have anything to do with
1073ff48bf5SDavid du ColombierPostScript, PDF, or page description languages.  Ghostscript itself follows
1083ff48bf5SDavid du Colombiersome additional conventions; these are documented separately under "<a
1093ff48bf5SDavid du Colombierhref="#Conventions">Ghostscript conventions</a>" below.
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier<hr>
1127dd7cddfSDavid du Colombier
1133ff48bf5SDavid du Colombier<h2><a name="C_language"></a>C language do's and don'ts</h2>
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier<p>
1163ff48bf5SDavid du ColombierThere are several different versions of the C language, and even of the ANSI
1173ff48bf5SDavid du ColombierC standard.  Ghostscript versions through 7.0 were designed to compile on
1183ff48bf5SDavid du Colombierpre-ANSI compilers as well as on many compilers that implemented the ANSI
1193ff48bf5SDavid du Colombierstandard with varying faithfulness.  Ghostscript versions since 7.0 do not
1203ff48bf5SDavid du Colombiercater for pre-ANSI compilers: they must conform to the ANSI 1989 standard
1213ff48bf5SDavid du Colombier(ANS X3.159-1989), with certain restrictions and a few conventional
1223ff48bf5SDavid du Colombieradditions.
1237dd7cddfSDavid du Colombier
1243ff48bf5SDavid du Colombier<h3>Preprocessor</h3>
1257dd7cddfSDavid du Colombier
1263ff48bf5SDavid du Colombier<h4><a name="Conditionals"></a>Conditionals</h4>
1277dd7cddfSDavid du Colombier
1283ff48bf5SDavid du ColombierRestrictions:
1297dd7cddfSDavid du Colombier
1303ff48bf5SDavid du Colombier<ul>
1313ff48bf5SDavid du Colombier
1323ff48bf5SDavid du Colombier<li>Don't assume that <b><tt>#if</tt></b> will treat undefined names as 0.
1333ff48bf5SDavid du ColombierWhile the ANSI standard requires this, it may produce a warning.
1343ff48bf5SDavid du Colombier
1353ff48bf5SDavid du Colombier<li>In <b><tt>.c</tt></b> files, don't use preprocessor conditionals that
1363ff48bf5SDavid du Colombiertest for individual platforms or compilers.  Use them only in header files
1373ff48bf5SDavid du Colombiernamed xxx<b><tt>_.h</tt></b>.
1383ff48bf5SDavid du Colombier
1393ff48bf5SDavid du Colombier</ul>
1403ff48bf5SDavid du Colombier
1413ff48bf5SDavid du Colombier<h4><a name="Macros"></a>Macros</h4>
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier<p>
1443ff48bf5SDavid du ColombierRestrictions:
1457dd7cddfSDavid du Colombier
1463ff48bf5SDavid du Colombier<ul>
1477dd7cddfSDavid du Colombier
1483ff48bf5SDavid du Colombier<li>Don't redefine a macro, even with the same definition, without using
1493ff48bf5SDavid du Colombier<b><tt>#undef</tt></b>.
1507dd7cddfSDavid du Colombier
1513ff48bf5SDavid du Colombier<li><b><tt>CAPITALIZE</tt></b> macro names unless there is a good reason not
1523ff48bf5SDavid du Colombierto.
1537dd7cddfSDavid du Colombier
154*593dc095SDavid du Colombier<li>Even though the legacy code contains some macros which contain
155*593dc095SDavid du Colombiercontrol flow statments, avoid the use of this in new code and do not
156*593dc095SDavid du Colombiercreate macros which contain hidden control flow, especially 'return'.
157*593dc095SDavid du ColombierThe use of control flow in macros complicates debug significantly
158*593dc095SDavid du Colombierrequiring tedious expansion of macros to build a module to be debugged
159*593dc095SDavid du Colombieror resorting to disassembly windows to set breakpoints or to trace
160*593dc095SDavid du Colombierflow.
161*593dc095SDavid du Colombier
1623ff48bf5SDavid du Colombier<li>Don't use a macro call within a macro argument if the call expands to a
1633ff48bf5SDavid du Colombiertoken sequence that includes any commas not within parentheses: this
1643ff48bf5SDavid du Colombierproduces different results depending on whether the compiler expands the
1653ff48bf5SDavid du Colombierinner call before or after the argument is substituted into the macro body.
1663ff48bf5SDavid du Colombier(The ANSI standard says that calls must be expanded after substitution, but
1673ff48bf5SDavid du Colombiersome compilers do it the other way.)
1687dd7cddfSDavid du Colombier
1693ff48bf5SDavid du Colombier<li>Don't use macro names, even inadvertently, in string constants.  Some
1703ff48bf5SDavid du Colombiercompilers erroneously try to expand them.
1717dd7cddfSDavid du Colombier
1723ff48bf5SDavid du Colombier<li>Don't use macros to define shorthands for casted pointers.  For
1733ff48bf5SDavid du Colombierinstance, avoid
1747dd7cddfSDavid du Colombier
1757dd7cddfSDavid du Colombier<blockquote><b><tt>
1767dd7cddfSDavid du Colombier#define fdev ((gx_device_fubar *)dev)
1777dd7cddfSDavid du Colombier</tt></b></blockquote>
1787dd7cddfSDavid du Colombier
1797dd7cddfSDavid du Colombier<p>
1807dd7cddfSDavid du Colombierand instead use
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier<blockquote><b><tt>
1837dd7cddfSDavid du Colombiergx_device_fubar * const fdev = (gx_device_fubar *)dev;
1847dd7cddfSDavid du Colombier</tt></b></blockquote>
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier<p>
1877dd7cddfSDavid du ColombierThe use of <b><tt>const</tt></b> alerts the reader that this is effectively
1887dd7cddfSDavid du Colombiera synonym.
1897dd7cddfSDavid du Colombier
1903ff48bf5SDavid du Colombier<li>If a macro generates anything larger than a single expression (that is,
1913ff48bf5SDavid du Colombierone or more statements), surround it with <b><tt>BEGIN</tt></b> and
1927dd7cddfSDavid du Colombier<b><tt>END</tt></b>.  These work around the fact that simple statements and
1937dd7cddfSDavid du Colombiercompound statements in C can't be substituted for each other syntactically.
1947dd7cddfSDavid du Colombier
195*593dc095SDavid du Colombier<li>If a macro introduces local variables, only use names that end with an
196*593dc095SDavid du Colombierunderscore (<b><tt>_</tt></b>), such as <b><tt>code_</tt></b>.  This avoids
197*593dc095SDavid du Colombierclashes both with ordinary variable names (which should never end with an
198*593dc095SDavid du Colombierunderscore) and with system-defined names (which may begin with an
199*593dc095SDavid du Colombierunderscore).
200*593dc095SDavid du Colombier
2013ff48bf5SDavid du Colombier</ul>
2023ff48bf5SDavid du Colombier
2033ff48bf5SDavid du Colombier<h3><a name="Preprocessor_other"></a>Other</h3>
2043ff48bf5SDavid du Colombier
2057dd7cddfSDavid du Colombier<p>
2063ff48bf5SDavid du ColombierRestrictions:
2073ff48bf5SDavid du Colombier
2083ff48bf5SDavid du Colombier<ul>
2093ff48bf5SDavid du Colombier
2103ff48bf5SDavid du Colombier<li>Only use <b><tt>#pragma</tt></b> in files that are explicitly identified
2113ff48bf5SDavid du Colombieras being platform-dependent.  Many compilers complain if this is used at
2123ff48bf5SDavid du Colombierall, and some complain if they don't recognize the specific pragma being
2133ff48bf5SDavid du Colombierrequested (both incorrect according to the ANSI standard).
2143ff48bf5SDavid du Colombier
2153ff48bf5SDavid du Colombier</ul>
2163ff48bf5SDavid du Colombier
2173ff48bf5SDavid du Colombier<h3><a name="Lexical_elements"></a>Lexical elements</h3>
2183ff48bf5SDavid du Colombier
2193ff48bf5SDavid du Colombier<p>
2203ff48bf5SDavid du ColombierDo not use:
2213ff48bf5SDavid du Colombier
2223ff48bf5SDavid du Colombier<ul>
2233ff48bf5SDavid du Colombier
2243ff48bf5SDavid du Colombier<li>ANSI trigraphs (??x)
2253ff48bf5SDavid du Colombier<li>Nested comments (/* /* */ */) (not ANSI compliant, but often accepted)
2263ff48bf5SDavid du Colombier<li>Multi-character character constants ('abc')
2273ff48bf5SDavid du Colombier<li>Wide-character character or string constants (L'x', L"x")
2283ff48bf5SDavid du Colombier
2293ff48bf5SDavid du Colombier</ul>
2303ff48bf5SDavid du Colombier
2313ff48bf5SDavid du Colombier<p>
2323ff48bf5SDavid du ColombierRestrictions:
2333ff48bf5SDavid du Colombier
2343ff48bf5SDavid du Colombier<ul>
2353ff48bf5SDavid du Colombier
2363ff48bf5SDavid du Colombier<li>Procedure and static variable names must be 31 characters or less.
2373ff48bf5SDavid du Colombier
2383ff48bf5SDavid du Colombier<li>Externally visible procedure and variable names must be unique in the
2393ff48bf5SDavid du Colombierfirst 23 characters.
2403ff48bf5SDavid du Colombier
2413ff48bf5SDavid du Colombier</ul>
2423ff48bf5SDavid du Colombier
2433ff48bf5SDavid du Colombier<h3><a name="Scoping"></a>Scoping (extern, static, ...)</h3>
2443ff48bf5SDavid du Colombier
2453ff48bf5SDavid du Colombier<p>
2463ff48bf5SDavid du ColombierDo not use:
2473ff48bf5SDavid du Colombier
2483ff48bf5SDavid du Colombier<ul>
2493ff48bf5SDavid du Colombier
2503ff48bf5SDavid du Colombier<li><b><tt>register</tt></b>
2513ff48bf5SDavid du Colombier
2523ff48bf5SDavid du Colombier</ul>
2533ff48bf5SDavid du Colombier
2543ff48bf5SDavid du Colombier<p>
2553ff48bf5SDavid du ColombierRestrictions:
2563ff48bf5SDavid du Colombier
2573ff48bf5SDavid du Colombier<ul>
2583ff48bf5SDavid du Colombier
2593ff48bf5SDavid du Colombier<li>Do not allow a global variable (constant) to have more than one
2603ff48bf5SDavid du Colombiernon-<b><tt>extern</tt></b> definition, even though some ANSI C compilers
2613ff48bf5SDavid du Colombierallow this.  Every global constant should have exactly one definition, in a
2623ff48bf5SDavid du Colombier<b><tt>.c</tt></b> file, and preferably just one <b><tt>extern</tt></b>
2633ff48bf5SDavid du Colombierdeclaration, in a header file.
2643ff48bf5SDavid du Colombier
2653ff48bf5SDavid du Colombier<li>Use <b><tt>private</tt></b> instead of <b><tt>static</tt></b> for
2663ff48bf5SDavid du Colombierprocedures and variables declared at the outermost scope of a file.  This
2673ff48bf5SDavid du Colombierallows making such constructs either visible or invisible to profilers by
2683ff48bf5SDavid du Colombierchanging a single <b><tt>#define</tt></b>.
2693ff48bf5SDavid du Colombier
2703ff48bf5SDavid du Colombier<li><b><tt>static</tt></b> or <b><tt>private</tt></b> variables must be
2713ff48bf5SDavid du Colombier<b><tt>const</tt></b> and initialized: non-<b><tt>const</tt></b> statically
2723ff48bf5SDavid du Colombierallocated variables are incompatible with reentrancy, and we're in the
2733ff48bf5SDavid du Colombierprocess of eliminating all of them.
2743ff48bf5SDavid du Colombier
2753ff48bf5SDavid du Colombier<li>Do not use <b><tt>extern</tt></b> in <b><tt>.c</tt></b> files, only in
2763ff48bf5SDavid du Colombier<b><tt>.h</tt></b> files, unless you have a very good reason for it (e.g.,
2773ff48bf5SDavid du Colombieras in <a href="../src/iconf.c">iconf.c</a>).  There are too many such
2783ff48bf5SDavid du Colombier<b><tt>extern</tt></b>s in the code now: we are eliminating them over time.
2793ff48bf5SDavid du Colombier
2803ff48bf5SDavid du Colombier<li>Do not declare the same name as both <b><tt>static</tt></b>
2813ff48bf5SDavid du Colombier(<b><tt>private</tt></b>) and non-<b><tt>static</tt></b> within the same
2823ff48bf5SDavid du Colombiercompilation.  (Some compilers complain, some do not.)  This is especially a
2833ff48bf5SDavid du Colombierproblem for procedures: it is easy to declare a procedure as
2843ff48bf5SDavid du Colombier<b><tt>private</tt></b> near the beginning of a file and accidentally not
2853ff48bf5SDavid du Colombierdeclare it <b><tt>private</tt></b> where it is defined later in the file.
2863ff48bf5SDavid du Colombier
2873ff48bf5SDavid du Colombier<li>Even though the ANSI standard allows initialized external declarations
2883ff48bf5SDavid du Colombier(<b><tt>extern&nbsp;int&nbsp;x&nbsp;=&nbsp;0</tt></b>), don't use them.
2893ff48bf5SDavid du Colombier
2903ff48bf5SDavid du Colombier</ul>
2913ff48bf5SDavid du Colombier
2923ff48bf5SDavid du Colombier<h3><a name="Scalars"></a>Scalars</h3>
2933ff48bf5SDavid du Colombier
2943ff48bf5SDavid du Colombier<p>
2953ff48bf5SDavid du ColombierRestrictions:
2963ff48bf5SDavid du Colombier
2973ff48bf5SDavid du Colombier<ul>
2983ff48bf5SDavid du Colombier
2993ff48bf5SDavid du Colombier<li>Avoid using <b><tt>char</tt></b>, except for <b><tt>char&nbsp;*</tt></b>
3003ff48bf5SDavid du Colombierfor a pointer to a string.  Don't assume that <b><tt>char</tt></b> is
3013ff48bf5SDavid du Colombiersigned; also don't assume it is unsigned.
3023ff48bf5SDavid du Colombier
3033ff48bf5SDavid du Colombier<li>Never cast a <b><tt>float</tt></b> to a <b><tt>double</tt></b>
3043ff48bf5SDavid du Colombierexplicitly.  ANSI compilers in their default mode do all floating point
3053ff48bf5SDavid du Colombiercomputations in double precision, and handle such casts automatically.
3063ff48bf5SDavid du Colombier
3073ff48bf5SDavid du Colombier<li>Don't use <b><tt>long long</tt></b>: even though it is in the ANSI
3083ff48bf5SDavid du Colombierstandard, not all compilers support it.  Use <b><tt>bits64</tt></b> instead
3093ff48bf5SDavid du Colombier(see below under "<a href="#Language_extensions">Language extensions</a>").
3103ff48bf5SDavid du Colombier
3113ff48bf5SDavid du Colombier<li>Don't assume anything about whether <b><tt>sizeof(long)</tt></b> is less
3123ff48bf5SDavid du Colombierthan, equal to, or greater than <b><tt>sizeof(ptr)</tt></b>.  (However, you
3133ff48bf5SDavid du Colombiercan make such comparisons in preprocessor conditionals using
3143ff48bf5SDavid du Colombier<b><tt>ARCH_SIZEOF_LONG</tt></b> and <b><tt>ARCH_SIZEOF_PTR</tt></b>.)
3153ff48bf5SDavid du Colombier
3163ff48bf5SDavid du Colombier</ul>
3173ff48bf5SDavid du Colombier
3183ff48bf5SDavid du Colombier<h3><a name="Arrays"></a>Arrays</h3>
3193ff48bf5SDavid du Colombier
3203ff48bf5SDavid du Colombier<p>
3213ff48bf5SDavid du ColombierRestrictions:
3223ff48bf5SDavid du Colombier
3233ff48bf5SDavid du Colombier<ul>
3243ff48bf5SDavid du Colombier
3253ff48bf5SDavid du Colombier<li>Don't declare arrays of size 0.  (The newer ANSI standard allows this,
3263ff48bf5SDavid du Colombierbut the older one doesn't.)
3273ff48bf5SDavid du Colombier
3283ff48bf5SDavid du Colombier<li>Don't declare an array of size 1 at the end of a structure to indicate
3293ff48bf5SDavid du Colombierthat a variable-size array follows.
3303ff48bf5SDavid du Colombier
3313ff48bf5SDavid du Colombier<li>Don't declare initialized <b><tt>auto</tt></b> arrays.
3323ff48bf5SDavid du Colombier
3333ff48bf5SDavid du Colombier</ul>
3343ff48bf5SDavid du Colombier
3353ff48bf5SDavid du Colombier<h3><a name="Typedefs"></a>Typedefs</h3>
3363ff48bf5SDavid du Colombier
3373ff48bf5SDavid du Colombier<p>
3383ff48bf5SDavid du ColombierRestrictions:
3393ff48bf5SDavid du Colombier
3403ff48bf5SDavid du Colombier<ul>
3413ff48bf5SDavid du Colombier
3423ff48bf5SDavid du Colombier<li>Don't use <b><tt>typedef</tt></b> for function types, such as
3437dd7cddfSDavid du Colombier
3447dd7cddfSDavid du Colombier<blockquote>
3453ff48bf5SDavid du Colombier<b><tt>typedef int proc_xyz_t(double, int *);</tt></b>
3467dd7cddfSDavid du Colombier</blockquote>
3477dd7cddfSDavid du Colombier
3483ff48bf5SDavid du Colombier<p>Many compilers don't handle this correctly -- they will give errors, or
3493ff48bf5SDavid du Colombierdo the wrong thing, when declaring variables of type
3503ff48bf5SDavid du Colombier<b><tt>proc_xyz_t</tt></b> and/or <b><tt>proc_xyz_t *</tt></b>.  Instead, do
3513ff48bf5SDavid du Colombierthis:
3523ff48bf5SDavid du Colombier
3533ff48bf5SDavid du Colombier<blockquote>
3543ff48bf5SDavid du Colombier<b><tt>#define PROC_XYZ(proc) int proc(double, int *)<br>
3553ff48bf5SDavid du ColombierPROC_XYZ(some_proc);  /* declare a procedure of this type */<br>
3563ff48bf5SDavid du Colombiertypedef PROC_XYZ((*proc_xyz_ptr_t));  /* define a type for procedure ptrs */<br>
3573ff48bf5SDavid du Colombier<br>
3583ff48bf5SDavid du Colombierproc_xyz_ptr_t pp;  /* pointer to procedure */</tt></b>
3593ff48bf5SDavid du Colombier</blockquote>
3603ff48bf5SDavid du Colombier
3613ff48bf5SDavid du Colombier<li>Don't redefine <b><tt>typedef</tt></b>'ed names, even with the same
3623ff48bf5SDavid du Colombierdefinition.  Some compilers complain about this, and the standard doesn't
3633ff48bf5SDavid du Colombierallow it.
3643ff48bf5SDavid du Colombier
3653ff48bf5SDavid du Colombier</ul>
3663ff48bf5SDavid du Colombier
3673ff48bf5SDavid du Colombier<h3><a name="Structures"></a>Structures</h3>
3687dd7cddfSDavid du Colombier
3697dd7cddfSDavid du Colombier<p>
3703ff48bf5SDavid du ColombierRestrictions:
3717dd7cddfSDavid du Colombier
372*593dc095SDavid du Colombier<ul>
373*593dc095SDavid du Colombier
3743ff48bf5SDavid du Colombier<li>Don't use anonymous structures if you can possibly avoid it, except
3753ff48bf5SDavid du Colombieroccasionally as components of other structures. Ideally, use the
3763ff48bf5SDavid du Colombier<b><tt>struct</tt></b> keyword only for declaring named structure types,
3777dd7cddfSDavid du Colombierlike this:
3787dd7cddfSDavid du Colombier
3797dd7cddfSDavid du Colombier<blockquote>
3803ff48bf5SDavid du Colombier<b><tt>typedef struct xxx_s {</tt></b><br>
3817dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... members ...<br>
3823ff48bf5SDavid du Colombier<b><tt>} xxx_t;</tt></b>
3837dd7cddfSDavid du Colombier</blockquote>
3847dd7cddfSDavid du Colombier
3853ff48bf5SDavid du Colombier<li>Use <b><tt>struct</tt></b> only when declaring structure types, never
3863ff48bf5SDavid du Colombierfor referring to them (e.g., never declare a variable as type
3873ff48bf5SDavid du Colombier<b><tt>struct&nbsp;xxx_s&nbsp;*</tt></b>).
3883ff48bf5SDavid du Colombier
3893ff48bf5SDavid du Colombier<li>Don't assume that the compiler will (or won't) insert padding in
3903ff48bf5SDavid du Colombierstructures to align members for best performance.  To preserve alignment,
3913ff48bf5SDavid du Colombieronly declare structure members that are narrower than an <b><tt>int</tt></b>
3923ff48bf5SDavid du Colombierif there will be a lot of instances of that structure in memory.  For such
3933ff48bf5SDavid du Colombierstructures, insert <b><tt>byte</tt></b> and/or <b><tt>short</tt></b> padding
3943ff48bf5SDavid du Colombiermembers as necessary to re-establish <b><tt>int</tt></b> alignment.
3953ff48bf5SDavid du Colombier
3963ff48bf5SDavid du Colombier<li>Don't declare initialized <b><tt>auto</tt></b> structures.
3973ff48bf5SDavid du Colombier
3983ff48bf5SDavid du Colombier</ul>
3993ff48bf5SDavid du Colombier
4003ff48bf5SDavid du Colombier<h3><a name="Unions"></a>Unions</h3>
4017dd7cddfSDavid du Colombier
4027dd7cddfSDavid du Colombier<p>
4033ff48bf5SDavid du ColombierRestrictions:
4043ff48bf5SDavid du Colombier
4053ff48bf5SDavid du Colombier<ul>
4063ff48bf5SDavid du Colombier
4073ff48bf5SDavid du Colombier<li>Use unions only as components of structures, not as typedefs in their
4083ff48bf5SDavid du Colombierown right.
4093ff48bf5SDavid du Colombier
4103ff48bf5SDavid du Colombier<li>Don't attempt to initialize unions: not all compilers support this, even
4113ff48bf5SDavid du Colombierthough it is in the 1989 ANSI standard.
4123ff48bf5SDavid du Colombier
4133ff48bf5SDavid du Colombier</ul>
4143ff48bf5SDavid du Colombier
4153ff48bf5SDavid du Colombier<h3><a name="Expressions"></a>Expressions</h3>
4163ff48bf5SDavid du Colombier
4173ff48bf5SDavid du Colombier<p>
4183ff48bf5SDavid du ColombierRestrictions:
4193ff48bf5SDavid du Colombier
4203ff48bf5SDavid du Colombier<ul>
4213ff48bf5SDavid du Colombier
4223ff48bf5SDavid du Colombier<li>Don't assign a larger integer data type to a smaller one without a cast
4233ff48bf5SDavid du Colombier(<b><tt>int_x&nbsp;=&nbsp;long_y</tt></b>).
4243ff48bf5SDavid du Colombier
4253ff48bf5SDavid du Colombier<li>It's OK to use the address of a structure or array element
4263ff48bf5SDavid du Colombier(<b><tt>&p->e</tt></b>, <b><tt>&a[i]</tt></b>) locally, or pass it to a
4273ff48bf5SDavid du Colombierprocedure that won't store it, but don't store such an address in allocated
4283ff48bf5SDavid du Colombierstorage unless you're very sure of what you're doing.
4293ff48bf5SDavid du Colombier
4303ff48bf5SDavid du Colombier<li>Don't use conditional expressions with structure or union values.
4313ff48bf5SDavid du Colombier(Pointers to structures or unions are OK.)
4323ff48bf5SDavid du Colombier
4333ff48bf5SDavid du Colombier<li>For calling a variable or parameter procedure, use
4343ff48bf5SDavid du Colombier<b><tt>ptr-&gt;func(...)</tt></b>.  Some old code uses explicit indirection,
4353ff48bf5SDavid du Colombier<b><tt>(*ptr-&gt;func)(...)</tt></b>: don't use this in new code.
4363ff48bf5SDavid du Colombier
4373ff48bf5SDavid du Colombier<li>Don't write expressions that depend on order of evaluation, unless the
4383ff48bf5SDavid du Colombierorder is created explicitly by use of <b><tt>||</tt></b>,
4393ff48bf5SDavid du Colombier<b><tt>&amp;&amp;</tt></b>, <b><tt>?:</tt></b>, <b><tt>,</tt></b>, or
4403ff48bf5SDavid du Colombierfunction nesting (the arguments of a function must be evaluated before the
4413ff48bf5SDavid du Colombierfunction is called).  In particular, don't assume that the arguments of a
4423ff48bf5SDavid du Colombierfunction will be evaluated left-to-right, or that the left side of an
4433ff48bf5SDavid du Colombierassignment will be evaluated before the right.
4443ff48bf5SDavid du Colombier
4453ff48bf5SDavid du Colombier<li>Don't mix integer and enumerated types ad lib: treat enumerated types as
4463ff48bf5SDavid du Colombierdistinct from integer types, and use casts to convert between the two.
4473ff48bf5SDavid du Colombier(Some compilers generate warnings if you do not do this.)
4483ff48bf5SDavid du Colombier
4493ff48bf5SDavid du Colombier</ul>
4503ff48bf5SDavid du Colombier
4513ff48bf5SDavid du Colombier<h3><a name="Statements"></a>Statements</h3>
4523ff48bf5SDavid du Colombier
4533ff48bf5SDavid du Colombier<p>
4543ff48bf5SDavid du ColombierRestrictions:
4553ff48bf5SDavid du Colombier
4563ff48bf5SDavid du Colombier<ul>
4573ff48bf5SDavid du Colombier
4583ff48bf5SDavid du Colombier<li>If you use an expression as a statement, other than an assignment or a
4593ff48bf5SDavid du Colombierfunction call with <b><tt>void</tt></b> return value, enclose it explicitly
4603ff48bf5SDavid du Colombierin <b><tt>DISCARD()</tt></b>.
4613ff48bf5SDavid du Colombier
4623ff48bf5SDavid du Colombier<li>The type of the operand of a <b><tt>switch</tt></b> must match the type
4633ff48bf5SDavid du Colombierof the case labels, whether the labels are <b><tt>int</tt></b>s or the
4643ff48bf5SDavid du Colombiermembers of an <b><tt>enum</tt></b> type.  (Use a cast if necessary.)
4653ff48bf5SDavid du Colombier
4663ff48bf5SDavid du Colombier<li>It is OK for one case of a switch to "fall through" into another (i.e.,
4673ff48bf5SDavid du Colombierfor the statement just before a case label not to be a control transfer),
4683ff48bf5SDavid du Colombierbut a comment <b><tt>/*&nbsp;falls&nbsp;through&nbsp;*/</tt></b> is
4693ff48bf5SDavid du Colombierrequired.
4703ff48bf5SDavid du Colombier
4713ff48bf5SDavid du Colombier<li>If you are returning an error code specified explicitly (e.g.,
4723ff48bf5SDavid du Colombier<b><tt>return&nbsp;gs_error_rangecheck</tt></b> or
4733ff48bf5SDavid du Colombier<b><tt>return&nbsp;e_rangecheck</tt></b>), use
4743ff48bf5SDavid du Colombier<b><tt>return_error()</tt></b> rather than plain <b><tt>return</tt></b>.
4753ff48bf5SDavid du ColombierHowever, if the program is simply propagating an error code generated
4763ff48bf5SDavid du Colombierelsewhere, as opposed to generating the error, use <b><tt>return</tt></b>
4773ff48bf5SDavid du Colombier(e.g., <b><tt>if&nbsp;(code&nbsp;<&nbsp;0)&nbsp;return&nbsp;code</tt></b>).
4783ff48bf5SDavid du Colombier
4793ff48bf5SDavid du Colombier</ul>
4803ff48bf5SDavid du Colombier
4813ff48bf5SDavid du Colombier<h3><a name="Procedures"></a>Procedures</h3>
4823ff48bf5SDavid du Colombier
4833ff48bf5SDavid du Colombier<p>
4843ff48bf5SDavid du ColombierRestrictions:
4853ff48bf5SDavid du Colombier
4863ff48bf5SDavid du Colombier<ul>
4873ff48bf5SDavid du Colombier
4883ff48bf5SDavid du Colombier<li>Provide a prototype for every procedure, and make sure the prototype is
4893ff48bf5SDavid du Colombieravailable at every call site.  If the procedure is local to a file
4903ff48bf5SDavid du Colombier(<b><tt>private</tt></b>), the prototype should precede the procedure, in
4913ff48bf5SDavid du Colombierthe same file; if the procedure is global, the prototype should be in a
4923ff48bf5SDavid du Colombierheader file.
4933ff48bf5SDavid du Colombier
4943ff48bf5SDavid du Colombier<li>If a procedure parameter is itself a procedure, do list its parameter
4953ff48bf5SDavid du Colombiertypes rather than just using <b><tt>()</tt></b>.  For example,
4967dd7cddfSDavid du Colombier
4977dd7cddfSDavid du Colombier<blockquote><b><tt>
4983ff48bf5SDavid du Colombierint foo(int (*callback)(int, int));
4997dd7cddfSDavid du Colombier</tt></b></blockquote>
5007dd7cddfSDavid du Colombier
5017dd7cddfSDavid du Colombier<p>
5027dd7cddfSDavid du Colombierrather than just
5037dd7cddfSDavid du Colombier
5047dd7cddfSDavid du Colombier<blockquote><b><tt>
5053ff48bf5SDavid du Colombierint foo(int (*callback)());
5067dd7cddfSDavid du Colombier</tt></b></blockquote>
5077dd7cddfSDavid du Colombier
5083ff48bf5SDavid du Colombier<li>Don't use the <b><tt>P</tt></b>* macros in new code.  (See the
5093ff48bf5SDavid du ColombierProcedures section of <a href="#Language_extensions">Language extensions</a>
5103ff48bf5SDavid du Colombierbelow for more information.)
5117dd7cddfSDavid du Colombier
5123ff48bf5SDavid du Colombier<li>Always provide an explicit return type for procedures, in both the
5133ff48bf5SDavid du Colombierprototype and the definition: don't rely on the implicit declaration as
5143ff48bf5SDavid du Colombier<b><tt>int</tt></b>.
5153ff48bf5SDavid du Colombier
5163ff48bf5SDavid du Colombier<li>Don't use <b><tt>float</tt></b> as the return type of a procedure,
5173ff48bf5SDavid du Colombierunless there's a special reason.  Floating point hardware typically does
5183ff48bf5SDavid du Colombiereverything in double precision internally and has to do extra work to
5193ff48bf5SDavid du Colombierconvert between double and single precision.
5203ff48bf5SDavid du Colombier
5213ff48bf5SDavid du Colombier<li>Don't declare parameters as being of type <b><tt>float</tt></b>,
5227dd7cddfSDavid du Colombier<b><tt>short</tt></b>, or <b><tt>char</tt></b>.  If you do this and forget
5237dd7cddfSDavid du Colombierto include the prototype at a call site, ANSI compilers will generate
5247dd7cddfSDavid du Colombierincompatible calling sequences.  Use <b><tt>floatp</tt></b> (a synonym for
5257dd7cddfSDavid du Colombier<b><tt>double</tt></b>, mnemonic for "float parameter") instead of
5267dd7cddfSDavid du Colombier<b><tt>float</tt></b>, and use <b><tt>int</tt></b> or <b><tt>uint</tt></b>
5277dd7cddfSDavid du Colombierinstead of <b><tt>short</tt></b> or <b><tt>char</tt></b>.
5287dd7cddfSDavid du Colombier
5297dd7cddfSDavid du Colombier</ul>
5307dd7cddfSDavid du Colombier
5313ff48bf5SDavid du Colombier<h3><a name="Standard_library"></a>Standard library</h3>
5327dd7cddfSDavid du Colombier
5337dd7cddfSDavid du Colombier<p>
5343ff48bf5SDavid du ColombierRestrictions:
5357dd7cddfSDavid du Colombier
5363ff48bf5SDavid du Colombier<ul>
5377dd7cddfSDavid du Colombier
5383ff48bf5SDavid du Colombier<li>Only use library features that are documented in the established ANSI
5393ff48bf5SDavid du Colombierstandard (e.g., Harbison & Steele's book).  Do not use procedures that are
5403ff48bf5SDavid du Colombier"standards" promulgated by Microsoft (e.g., <b><tt>stricmp</tt></b>), or
5413ff48bf5SDavid du Colombieroriginate in BSD Unix (e.g., <b><tt>strcasecmp</tt></b>), or were added in
5423ff48bf5SDavid du Colombierlater versions of the standard such as C 9X.
5437dd7cddfSDavid du Colombier
5443ff48bf5SDavid du Colombier<li>Do not use any features from <b><tt>stdio.h</tt></b> that assume the
5453ff48bf5SDavid du Colombierexistence of <b><tt>stdin</tt></b>, <b><tt>stdout</tt></b>, or
5463ff48bf5SDavid du Colombier<b><tt>stderr</tt></b>.  See <a href="../src/gsio.h">gsio.h</a> for the full
5473ff48bf5SDavid du Colombierlist.  Instead, use <b><tt>gs_stdin</tt></b> et al.
5487dd7cddfSDavid du Colombier
5493ff48bf5SDavid du Colombier</ul>
5507dd7cddfSDavid du Colombier
5517dd7cddfSDavid du Colombier<hr>
5527dd7cddfSDavid du Colombier
5533ff48bf5SDavid du Colombier<h2><a name="Language_extensions"></a>Language extensions</h2>
5547dd7cddfSDavid du Colombier
5553ff48bf5SDavid du Colombier<h3>Scoping</h3>
5563ff48bf5SDavid du Colombier
5573ff48bf5SDavid du Colombier<dl>
5583ff48bf5SDavid du Colombier
5593ff48bf5SDavid du Colombier<dt><b><tt>inline</tt></b>
5603ff48bf5SDavid du Colombier
5613ff48bf5SDavid du Colombier<dd><b><tt>inline</tt></b> is available even if the compiler does not
5623ff48bf5SDavid du Colombiersupport it.  Be aware, however, that it may have no effect.  In particular,
5633ff48bf5SDavid du Colombierdo not use <b><tt>inline</tt></b> in header files.  Instead, use the
5643ff48bf5SDavid du Colombier<b><tt>extern_inline</tt></b> facility described just below.
5653ff48bf5SDavid du Colombier
5663ff48bf5SDavid du Colombier<dt><b><tt>extern_inline</tt></b>
5673ff48bf5SDavid du Colombier
5683ff48bf5SDavid du Colombier<dd>Compilers that do support <b><tt>inline</tt></b> vary in how they decide
5693ff48bf5SDavid du Colombierwhether to (also) compile a closed-code copy of the procedure.  Because of
5703ff48bf5SDavid du Colombierthis, putting an <b><tt>inline</tt></b> procedure in a header file may
5713ff48bf5SDavid du Colombierproduce multiple closed copies, causing duplicate name errors at link time.
5723ff48bf5SDavid du Colombier<b><tt>extern_inline</tt></b> provides a safe way to put
5733ff48bf5SDavid du Colombier<b><tt>inline</tt></b> procedures in header files, regardless of compiler.
5743ff48bf5SDavid du ColombierUnfortunately, the only way we've found to make this fully portable involves
5753ff48bf5SDavid du Colombiera fair amount of boilerplate.  For details, please see <a
5763ff48bf5SDavid du Colombierhref="../src/stdpre.h">stdpre.h</a>.
5773ff48bf5SDavid du Colombier
5783ff48bf5SDavid du Colombier<dt><b><tt>private</tt></b>
5793ff48bf5SDavid du Colombier
5803ff48bf5SDavid du Colombier<dd><b>Use <tt>private</tt></b> instead of <b><tt>static</tt></b> for all
5813ff48bf5SDavid du Colombierfile-local procedures, and also for file-local variables defined at the
5823ff48bf5SDavid du Colombieroutermost level.  However, use <b><tt>static</tt></b>, not
5833ff48bf5SDavid du Colombier<b><tt>private</tt></b>, for variables defined within a procedure.
5843ff48bf5SDavid du Colombier
5853ff48bf5SDavid du Colombier<p>
5863ff48bf5SDavid du Colombier<b><tt>private</tt></b> is normally #define'd as <b><tt>static</tt></b>.
5873ff48bf5SDavid du ColombierHowever, it can also be #define'd as empty, which allows profilers to
5883ff48bf5SDavid du Colombiermeasure all procedures, and 'nm' to list all interesting statically
5893ff48bf5SDavid du Colombierallocated variables, not just public ones.
5903ff48bf5SDavid du Colombier
5913ff48bf5SDavid du Colombier</dl>
5923ff48bf5SDavid du Colombier
5933ff48bf5SDavid du Colombier<h3>Scalar types</h3>
5943ff48bf5SDavid du Colombier
5953ff48bf5SDavid du Colombier<dl>
5963ff48bf5SDavid du Colombier
5973ff48bf5SDavid du Colombier<dt><b><tt>bool, true, false</tt></b>
5983ff48bf5SDavid du Colombier
5993ff48bf5SDavid du Colombier<dd><b><tt>bool</tt></b> is intended as a Boolean type, with canonical
6003ff48bf5SDavid du Colombiervalues <b><tt>true</tt></b> and <b><tt>false</tt></b>.  In a more reasonable
6013ff48bf5SDavid du Colombierlanguage, such as Java, <b><tt>bool</tt></b> is an enumerated type requiring
6023ff48bf5SDavid du Colombieran explicit cast to or from <b><tt>int</tt></b>; however, because C's
6033ff48bf5SDavid du Colombierconditionals are defined as producing <b><tt>int</tt></b> values, we can't
6043ff48bf5SDavid du Colombiereven define <b><tt>bool</tt></b> as a C <b><tt>enum</tt></b> without
6053ff48bf5SDavid du Colombierprovoking compiler warnings.
6063ff48bf5SDavid du Colombier
6073ff48bf5SDavid du Colombier<p>
6083ff48bf5SDavid du ColombierEven though <b><tt>bool</tt></b> is a synonym for <b><tt>int</tt></b>, treat
6093ff48bf5SDavid du Colombierthem as conceptually different types:
6103ff48bf5SDavid du Colombier
6113ff48bf5SDavid du Colombier<ul>
6123ff48bf5SDavid du Colombier<li>Initialize or set <b><tt>bool</tt></b> variables to <b><tt>true</tt></b>
6133ff48bf5SDavid du Colombieror <b><tt>false</tt></b>, not 0 or 1.
6143ff48bf5SDavid du Colombier<li>Use the Boolean operators <b><tt>!</tt></b>, <b><tt>&&</tt></b>,
6153ff48bf5SDavid du Colombierand <b><tt>||</tt></b> only with Booleans.  Don't use the idiom
6163ff48bf5SDavid du Colombier<b><tt>!!x</tt></b> to create a Boolean that is true iff <b><tt>x</tt></b>
6173ff48bf5SDavid du Colombier!= 0: use <b><tt>x != 0</tt></b>.
6183ff48bf5SDavid du Colombier<li>Use an explicit <b><tt>(int)</tt></b> cast to convert a Boolean to an
6193ff48bf5SDavid du Colombierinteger.
6203ff48bf5SDavid du Colombier</ul>
6213ff48bf5SDavid du Colombier
6223ff48bf5SDavid du Colombier<dt><b><tt>byte, ushort, uint, ulong</tt></b>
6233ff48bf5SDavid du Colombier
6243ff48bf5SDavid du Colombier<dd>These types are simply shorthands for <b><tt>unsigned char, short, int,
6253ff48bf5SDavid du Colombierlong</tt></b>.
6263ff48bf5SDavid du Colombier
627*593dc095SDavid du Colombier<p>
628*593dc095SDavid du ColombierIn addition, the use of <b><tt>byte *</tt></b> indicates a
629*593dc095SDavid du ColombierGhostscript-style string, with explicit length given separately, as
630*593dc095SDavid du Colombieropposed to a null terminated C-style string, which is <b><tt>char
631*593dc095SDavid du Colombier*</tt></b>.
632*593dc095SDavid du Colombier
6333ff48bf5SDavid du Colombier<dt><b><tt>floatp</tt></b>
6343ff48bf5SDavid du Colombier
6353ff48bf5SDavid du Colombier<dd>This is a synonym for <b><tt>double</tt></b>.  It should be used for,
6363ff48bf5SDavid du Colombierand only for, procedure parameters that would otherwise be
6373ff48bf5SDavid du Colombier<b><tt>float</tt></b>.  (As noted above, procedure parameters should not be
6383ff48bf5SDavid du Colombierdeclared as <b><tt>float</tt></b>.)
6393ff48bf5SDavid du Colombier
6403ff48bf5SDavid du Colombier<dt><b><tt>bits8, bits16, bits32</tt></b>
6413ff48bf5SDavid du Colombier
6423ff48bf5SDavid du Colombier<dd>These are unsigned integer types of the given width.  Use them wherever
6433ff48bf5SDavid du Colombierthe actual width matters: do <em>not</em>, for example, use
6443ff48bf5SDavid du Colombier<b><tt>short</tt></b> assuming that it is 16 bits wide.
6453ff48bf5SDavid du Colombier
6463ff48bf5SDavid du Colombier<dt><b><tt>bits64</tt></b>
6473ff48bf5SDavid du Colombier
6483ff48bf5SDavid du Colombier<dd><strong>****** NOT IMPLEMENTED YET ******</strong>
6493ff48bf5SDavid du ColombierThis is an unsigned 64-bit integer type, but it may not be available on all
6503ff48bf5SDavid du Colombierplatforms.  Any code that uses this type should be surrounded by
6513ff48bf5SDavid du Colombier<b><tt>#if&nbsp;ARCH_HAS_BITS64</tt></b>.
6523ff48bf5SDavid du Colombier
6533ff48bf5SDavid du Colombier</dl>
6543ff48bf5SDavid du Colombier
6553ff48bf5SDavid du Colombier<hr>
6563ff48bf5SDavid du Colombier
6573ff48bf5SDavid du Colombier<h2><a name="Stylistic_conventions"></a>Stylistic conventions</h2>
6583ff48bf5SDavid du Colombier
6593ff48bf5SDavid du Colombier<p>
6603ff48bf5SDavid du ColombierGhostscript's coding rules cover not only the use of the language, but also
6613ff48bf5SDavid du Colombiermany stylistic issues like the choice of names and the use of whitespace.
6623ff48bf5SDavid du ColombierThe stylistic rules are meant to produce code that is easy to read.  It's
6633ff48bf5SDavid du Colombierimportant to observe them as much as possible in order to maintain a
6643ff48bf5SDavid du Colombierconsistent style, but if you find these rules getting in your way or
6653ff48bf5SDavid du Colombierproducing ugly-looking results once in a while, it's OK to break it.
6663ff48bf5SDavid du Colombier
6673ff48bf5SDavid du Colombier<h3><a name="Formatting"></a>Formatting</h3>
6683ff48bf5SDavid du Colombier
6693ff48bf5SDavid du Colombier<h4><a name="Indentation"></a>Indentation</h4>
6707dd7cddfSDavid du Colombier
6717dd7cddfSDavid du Colombier<p>
6727dd7cddfSDavid du ColombierWe've formatted all of our code using the GNU <b><tt>indent</tt></b> program.
6737dd7cddfSDavid du Colombier
6747dd7cddfSDavid du Colombier<blockquote><b><tt>
6757dd7cddfSDavid du Colombierindent&nbsp;-bad&nbsp;-nbap&nbsp;-nsob&nbsp;-br&nbsp;-ce&nbsp;-cli4&nbsp;-npcs&nbsp;-ncs&nbsp;\<br>
6767dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;-i4&nbsp;-di0&nbsp;-psl&nbsp;-lp&nbsp;-lps&nbsp;somefile.c
6777dd7cddfSDavid du Colombier</tt></b></blockquote>
6787dd7cddfSDavid du Colombier
6797dd7cddfSDavid du Colombier<p>
6807dd7cddfSDavid du Colombierdoes a 98% accurate job of producing our preferred style.  Unfortunately,
6817dd7cddfSDavid du Colombierthere are bugs in all versions of GNU <b><tt>indent</tt></b>, requiring
6827dd7cddfSDavid du Colombierboth pre- and post-processing of the code.  The <b><tt>gsindent</tt></b>
6837dd7cddfSDavid du Colombierscript in the Ghostscript fileset contains the necessary workarounds.
6847dd7cddfSDavid du Colombier
6857dd7cddfSDavid du Colombier<p>
6867dd7cddfSDavid du ColombierPut indentation points every 4 spaces, with 8 spaces = 1 tab stop.
6877dd7cddfSDavid du Colombier
6887dd7cddfSDavid du Colombier<p>
689*593dc095SDavid du ColombierDon't indent the initial <b><tt>#</tt></b> of preprocessor commands.
690*593dc095SDavid du ColombierHowever, for nested preprocessor commands, do use indentation between the
691*593dc095SDavid du Colombier<b><tt>#</tt></b> and the command itself.  Use 2 spaces per level of
692*593dc095SDavid du Colombiernesting, e.g.:
693*593dc095SDavid du Colombier
694*593dc095SDavid du Colombier<blockquote>
695*593dc095SDavid du Colombier<b><tt>#ifndef&nbsp;xyz</tt></b><br>
696*593dc095SDavid du Colombier<b><tt>#&nbsp;&nbsp;define&nbsp;xyz&nbsp;0</tt></b><br>
697*593dc095SDavid du Colombier<b><tt>#endif</tt></b>
698*593dc095SDavid du Colombier</blockquote>
699*593dc095SDavid du Colombier
700*593dc095SDavid du Colombier<p>
7013ff48bf5SDavid du ColombierFor assignments (including chain assignments), put the entire statement on
7023ff48bf5SDavid du Colombierone line if it will fit; if not, break it after a <b><tt>=</tt></b> and
7033ff48bf5SDavid du Colombierindent all the following lines.  I.e., format like this:
7043ff48bf5SDavid du Colombier
7053ff48bf5SDavid du Colombier<blockquote>
7063ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b>&nbsp;value<b><tt>;</tt></b><br>
7073ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b>&nbsp;var2&nbsp;<b><tt>=</tt></b>&nbsp;value<b><tt>;</tt></b><br>
7083ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b><br>
7093ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;value<b><tt>;</tt></b><br>
7103ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b><br>
7113ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;var2&nbsp;<b><tt>=</tt></b>&nbsp;value<b><tt>;</tt></b><br>
7123ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b>&nbsp;var2&nbsp;<b><tt>=</tt></b><br>
7133ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;value<b><tt>;</tt></b>
7143ff48bf5SDavid du Colombier</blockquote>
7153ff48bf5SDavid du Colombier
7163ff48bf5SDavid du Colombier<p>
7173ff48bf5SDavid du ColombierBut not like this:
7183ff48bf5SDavid du Colombier
7193ff48bf5SDavid du Colombier<blockquote>
7203ff48bf5SDavid du Colombiervar1&nbsp;<b><tt>=</tt></b><br>
7213ff48bf5SDavid du Colombiervar2&nbsp;<b><tt>=</tt></b> value<b><tt>;</tt></b>
7223ff48bf5SDavid du Colombier</blockquote>
7233ff48bf5SDavid du Colombier
7243ff48bf5SDavid du Colombier<p>
7257dd7cddfSDavid du ColombierIndent in-line blocks thus:
7267dd7cddfSDavid du Colombier
7277dd7cddfSDavid du Colombier<blockquote>
7287dd7cddfSDavid du Colombier<b><tt>{</tt></b><br>
7297dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... declarations ...<br>
7307dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;{{ blank line if any declarations above }}<br>
7317dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... statements ...<br>
7327dd7cddfSDavid du Colombier<b><tt>}</tt></b>
7337dd7cddfSDavid du Colombier</blockquote>
7347dd7cddfSDavid du Colombier
7357dd7cddfSDavid du Colombier<p>
7367dd7cddfSDavid du ColombierSimilarly, indent procedures thus:
7377dd7cddfSDavid du Colombier
7387dd7cddfSDavid du Colombier<blockquote>
7397dd7cddfSDavid du Colombierreturn_type<br>
7407dd7cddfSDavid du Colombierproc_name(... arguments ...)<br>
7417dd7cddfSDavid du Colombier<b><tt>{</tt></b><br>
7427dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... declarations ...<br>
7437dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;{{ blank line if any declarations above }}<br>
7447dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... statements ...<br>
7457dd7cddfSDavid du Colombier<b><tt>}</tt></b>
7467dd7cddfSDavid du Colombier</blockquote>
7477dd7cddfSDavid du Colombier
7487dd7cddfSDavid du Colombier<p>
7497dd7cddfSDavid du ColombierIf a control construct (<b><tt>if</tt></b>, <b><tt>do</tt></b>,
7507dd7cddfSDavid du Colombier<b><tt>while</tt></b>, or <b><tt>for</tt></b>) has a one-line body, use
7517dd7cddfSDavid du Colombierthis:
7527dd7cddfSDavid du Colombier
7537dd7cddfSDavid du Colombier<blockquote>
7547dd7cddfSDavid du Colombier... control construct ...<br>
7557dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate simple statement ...
7567dd7cddfSDavid du Colombier</blockquote>
7577dd7cddfSDavid du Colombier
7587dd7cddfSDavid du Colombier<p>
7597dd7cddfSDavid du ColombierIf it has a multi-line body, use this:
7607dd7cddfSDavid du Colombier
7617dd7cddfSDavid du Colombier<blockquote>
7627dd7cddfSDavid du Colombier... control construct ... <b><tt>{</tt></b><br>
7637dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7647dd7cddfSDavid du Colombier<b><tt>}</tt></b>
7657dd7cddfSDavid du Colombier</blockquote>
7667dd7cddfSDavid du Colombier
7677dd7cddfSDavid du Colombier<p>
7687dd7cddfSDavid du ColombierIf the subordinate code has declarations, see blocks above.
7697dd7cddfSDavid du Colombier
7707dd7cddfSDavid du Colombier<p>
7717dd7cddfSDavid du ColombierFor if-else statements, do this:
7727dd7cddfSDavid du Colombier
7737dd7cddfSDavid du Colombier<blockquote>
7747dd7cddfSDavid du Colombier<b><tt>if (</tt></b> ...<b><tt> ) {</tt></b><br>
7757dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7767dd7cddfSDavid du Colombier<b><tt>} else if (</tt></b> ...<b><tt> ) {</tt></b><br>
7777dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7787dd7cddfSDavid du Colombier<b><tt>} else {</tt></b><br>
7797dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7807dd7cddfSDavid du Colombier<b><tt>}</tt></b>
7817dd7cddfSDavid du Colombier</blockquote>
7827dd7cddfSDavid du Colombier
7837dd7cddfSDavid du Colombier<p>
7847dd7cddfSDavid du ColombierWhen there are more than two alternatives, as in the example above, use the
7857dd7cddfSDavid du Colombierabove ("parallel") syntax rather than the following ("nested") syntax:
7867dd7cddfSDavid du Colombier
7877dd7cddfSDavid du Colombier<blockquote>
7887dd7cddfSDavid du Colombier<b><tt>if (</tt></b> ...<b><tt> ) {</tt></b><br>
7897dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7907dd7cddfSDavid du Colombier<b><tt>} else {</tt></b><br>
7917dd7cddfSDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;if (</tt></b> ...<b><tt> ) {</tt></b><br>
7927dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7937dd7cddfSDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;} else {</tt></b><br>
7947dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... subordinate code ...<br>
7957dd7cddfSDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;}</tt></b><br>
7967dd7cddfSDavid du Colombier<b><tt>}</tt></b>
7977dd7cddfSDavid du Colombier</blockquote>
7987dd7cddfSDavid du Colombier
7997dd7cddfSDavid du Colombier<p>
8007dd7cddfSDavid du ColombierSimilarly, for do-while statements, do this:
8017dd7cddfSDavid du Colombier
8027dd7cddfSDavid du Colombier<blockquote>
8037dd7cddfSDavid du Colombier<b><tt>do {</tt></b><br>
8047dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;... body ...<br>
8057dd7cddfSDavid du Colombier<b><tt>} while (</tt></b> ... condition ... <b><tt>);</tt></b>
8067dd7cddfSDavid du Colombier</blockquote>
8077dd7cddfSDavid du Colombier
8083ff48bf5SDavid du Colombier<h4><a name="Spaces"></a>Spaces</h4>
8097dd7cddfSDavid du Colombier
8107dd7cddfSDavid du Colombier<p>
8117dd7cddfSDavid du ColombierDo put a space:
8127dd7cddfSDavid du Colombier<ul>
8137dd7cddfSDavid du Colombier<li>after every comma and semicolon, unless it ends a line;
8143ff48bf5SDavid du Colombier<li>around every binary operator other than "<b><tt>-&gt;</tt></b>" and
8153ff48bf5SDavid du Colombier"<b><tt>.</tt></b>", although you can omit the spaces around the innermost
8163ff48bf5SDavid du Colombieroperator in a nested expression if you like;
8177dd7cddfSDavid du Colombier<li>on both sides of the parentheses of an <b><tt>if</tt></b>, <b><tt>for</tt></b>, or <b><tt>while</tt></b>.
8187dd7cddfSDavid du Colombier</ul>
8197dd7cddfSDavid du Colombier
8207dd7cddfSDavid du Colombier<p>
8217dd7cddfSDavid du ColombierDon't put a space:
8227dd7cddfSDavid du Colombier<ul>
8237dd7cddfSDavid du Colombier<li>at the end of a line;
8247dd7cddfSDavid du Colombier<li>before a comma or semicolon;
8257dd7cddfSDavid du Colombier<li>after unary prefix operators;
8267dd7cddfSDavid du Colombier<li>before the parenthesis of a macro or procedure call.
8277dd7cddfSDavid du Colombier</ul>
8287dd7cddfSDavid du Colombier
8293ff48bf5SDavid du Colombier<h4><a name="Parentheses"></a>Parentheses</h4>
8307dd7cddfSDavid du Colombier
8317dd7cddfSDavid du Colombier<p>
8327dd7cddfSDavid du ColombierParentheses are important in only a few places:
8337dd7cddfSDavid du Colombier
8347dd7cddfSDavid du Colombier<ul>
8357dd7cddfSDavid du Colombier<li>Around the inner subexpressions in expressions that mix
8367dd7cddfSDavid du Colombier<b><tt>&amp;&amp;</tt></b> and <b><tt>||</tt></b>, even if they are not
8377dd7cddfSDavid du Colombierrequired by precedence, for example
8387dd7cddfSDavid du Colombier
8397dd7cddfSDavid du Colombier<blockquote><b><tt>
8407dd7cddfSDavid du Colombier(xx &amp;&amp; yy) || zz
8417dd7cddfSDavid du Colombier</tt></b></blockquote>
8427dd7cddfSDavid du Colombier
8437dd7cddfSDavid du Colombier<li>Similarly around inner subexpressions in expressions that mix
8447dd7cddfSDavid du Colombier<b><tt>&amp;</tt></b>, <b><tt>|</tt></b>, or shifts, especially if mixing
8457dd7cddfSDavid du Colombierthese with other operators, for instance
8467dd7cddfSDavid du Colombier
8477dd7cddfSDavid du Colombier<blockquote><b><tt>
8487dd7cddfSDavid du Colombier(x &lt;&lt; 3) | (y &gt;&gt; 5)
8497dd7cddfSDavid du Colombier</tt></b></blockquote>
8507dd7cddfSDavid du Colombier
8517dd7cddfSDavid du Colombier<li>In macro definitions around every use of an argument that logically
8527dd7cddfSDavid du Colombiercould be an expression, for example
8537dd7cddfSDavid du Colombier
8547dd7cddfSDavid du Colombier<blockquote><b><tt>
8557dd7cddfSDavid du Colombier((x) * (x) + (y) * (y))
8567dd7cddfSDavid du Colombier</tt></b></blockquote>
8577dd7cddfSDavid du Colombier
8587dd7cddfSDavid du Colombier</ul>
8597dd7cddfSDavid du Colombier
8607dd7cddfSDavid du Colombier<p>
8617dd7cddfSDavid du ColombierAnywhere else, given the choice, use fewer parentheses.
8627dd7cddfSDavid du Colombier
8637dd7cddfSDavid du Colombier<p>
8647dd7cddfSDavid du ColombierFor stylistic consistency with the existing Ghostscript code, put
8657dd7cddfSDavid du Colombierparentheses around conditional expressions even if they aren't
8667dd7cddfSDavid du Colombiersyntactically required, unless you really dislike doing this.  Note that
8677dd7cddfSDavid du Colombierthe parentheses should go around the entire expression, not the condition.
8687dd7cddfSDavid du ColombierFor instance, instead of
8697dd7cddfSDavid du Colombier
8707dd7cddfSDavid du Colombier<blockquote><b><tt>
8717dd7cddfSDavid du Colombierhpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br>
8727dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;(pgls-&gt;g.pen_down) ? gs_lineto : gs_moveto);
8737dd7cddfSDavid du Colombier</tt></b></blockquote>
8747dd7cddfSDavid du Colombier
8757dd7cddfSDavid du Colombier<p>
8767dd7cddfSDavid du Colombieruse
8777dd7cddfSDavid du Colombier
8787dd7cddfSDavid du Colombier<blockquote><b><tt>
8797dd7cddfSDavid du Colombierhpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br>
8807dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;(pgls-&gt;g.pen_down ? gs_lineto : gs_moveto));
8817dd7cddfSDavid du Colombier</tt></b></blockquote>
8827dd7cddfSDavid du Colombier
8833ff48bf5SDavid du Colombier<h3><a name="Preprocessor_style"></a>Preprocessor</h3>
8847dd7cddfSDavid du Colombier
8853ff48bf5SDavid du Colombier<h4>Conditionals</h4>
8867dd7cddfSDavid du Colombier
8873ff48bf5SDavid du Colombier<p>
8883ff48bf5SDavid du ColombierUsing preprocessor conditionals can easily lead to unreadable code, since
8893ff48bf5SDavid du Colombierthe eye really wants to read linearly rather than having to parse the
8903ff48bf5SDavid du Colombierconditionals just to figure out what code is relevant.  It's OK to use
8913ff48bf5SDavid du Colombierconditionals that have small scope and that don't change the structure or
8923ff48bf5SDavid du Colombierlogic of the program (typically, they select between different sets of
8933ff48bf5SDavid du Colombiervalues depending on some configuration parameter), but where possible, break
8943ff48bf5SDavid du Colombierup source modules rather than use conditionals that affect the structure or
8953ff48bf5SDavid du Colombierlogic.
8963ff48bf5SDavid du Colombier
8973ff48bf5SDavid du Colombier<h4>Macros</h4>
8983ff48bf5SDavid du Colombier
8993ff48bf5SDavid du Colombier<p>
9003ff48bf5SDavid du ColombierGhostscript code uses macros heavily to effectively extend the rather
9013ff48bf5SDavid du Colombierweak abstraction capabilities of the C language, specifically in the area of
9023ff48bf5SDavid du Colombiermemory management and garbage collection: in order to read Ghostscript code
9033ff48bf5SDavid du Colombiereffectively, you simply have to learn some of these macros as though they
9043ff48bf5SDavid du Colombierwere part of the language.  The current code also uses macros heavily for
9053ff48bf5SDavid du Colombierother purposes, but we are trying to phase these out as rapidly as possible,
9063ff48bf5SDavid du Colombierbecause they make the code harder to read and debug, and to use the
9073ff48bf5SDavid du Colombierrules that follow consistently in new code.
9083ff48bf5SDavid du Colombier
9093ff48bf5SDavid du Colombier<p>
9103ff48bf5SDavid du ColombierDefine macros in the smallest scope you can manage (procedure, file, or
9113ff48bf5SDavid du Colombier<b><tt>.h</tt></b> file), and <b><tt>#undef</tt></b> them at the end of
9123ff48bf5SDavid du Colombierthat scope: that way, someone reading the code can see the definitions
9133ff48bf5SDavid du Colombiereasily when reading the uses.  If that isn't appropriate, define them in as
9143ff48bf5SDavid du Colombierlarge a scope as possible, so that they effectively become part of the
9153ff48bf5SDavid du Colombierlanguage.  This places an additional burden on the reader, but it can be
9163ff48bf5SDavid du Colombieramortized over reading larger amounts of code.
9173ff48bf5SDavid du Colombier
9183ff48bf5SDavid du Colombier<p>
9193ff48bf5SDavid du ColombierTry hard to use procedures instead of macros.  Use "<b><tt>inline</tt></b>"
9203ff48bf5SDavid du Colombierif you really think the extra speed is needed, but only within a
9213ff48bf5SDavid du Colombier<b><tt>.c</tt></b> file: don't put inline procedures in <b><tt>.h</tt></b>
9223ff48bf5SDavid du Colombierfiles, because most compilers don't honor "<b><tt>inline</tt></b>" and
9233ff48bf5SDavid du Colombieryou'll wind up with a copy of the procedure in every <b><tt>.c</tt></b>
9243ff48bf5SDavid du Colombierfile that includes the <b><tt>.h</tt></b> file.
9253ff48bf5SDavid du Colombier
9263ff48bf5SDavid du Colombier<p>
9273ff48bf5SDavid du ColombierIf you define a macro that looks like a procedure, make sure it will work
9283ff48bf5SDavid du Colombierwherever a procedure will work.  In particular, put parentheses around every
9293ff48bf5SDavid du Colombieruse of an argument within the macro body, so that the macro will parse
9303ff48bf5SDavid du Colombiercorrectly if some of the arguments are expressions, and put parentheses
9313ff48bf5SDavid du Colombieraround the entire macro body.  (This is still subject to the problem that an
9323ff48bf5SDavid du Colombierargument may be evaluated more than once, but there is no way around this in
9333ff48bf5SDavid du ColombierC, since C doesn't provide for local variables within expressions.)
9343ff48bf5SDavid du Colombier
9353ff48bf5SDavid du Colombier<p>
9363ff48bf5SDavid du ColombierIf you define macros for special loop control structures, make their uses
9373ff48bf5SDavid du Colombierlook somewhat like ordinary loops, for instance:
9383ff48bf5SDavid du Colombier
9393ff48bf5SDavid du Colombier<blockquote>
9403ff48bf5SDavid du Colombier<b><tt>BEGIN_RECT(xx, yy) {</tt></b><br>
9413ff48bf5SDavid du Colombier&nbsp;&nbsp;... body indented one position ...<br>
9423ff48bf5SDavid du Colombier<b><tt>} END_RECT(xx, yy);</tt></b>
9433ff48bf5SDavid du Colombier</blockquote>
9443ff48bf5SDavid du Colombier
9453ff48bf5SDavid du Colombier<p>
9463ff48bf5SDavid du ColombierIf at all possible, don't use free variables in macros -- that is, variables
9473ff48bf5SDavid du Colombierthat aren't apparent as arguments of the macro.  If you must use free
9483ff48bf5SDavid du Colombiervariables, list them all in a comment at the point where the macro is
9493ff48bf5SDavid du Colombierdefined.
9503ff48bf5SDavid du Colombier
951*593dc095SDavid du Colombier<p>
952*593dc095SDavid du ColombierIf you define new macros or groups of macros, especially if they aren't
953*593dc095SDavid du Colombiersimply inline procedures or named constant values, put some extra effort
954*593dc095SDavid du Colombierinto documenting them, to compensate for the fact that macros are
955*593dc095SDavid du Colombierintrinsically harder to understand than procedures.
956*593dc095SDavid du Colombier
9573ff48bf5SDavid du Colombier<h3><a name="Comments"></a>Comments</h3>
9583ff48bf5SDavid du Colombier
9593ff48bf5SDavid du Colombier<p>
9603ff48bf5SDavid du ColombierThe most important descriptive comments are ones in header files that
9613ff48bf5SDavid du Colombierdescribe structures, including invariants; but every procedure or structure
9623ff48bf5SDavid du Colombierdeclaration, or group of other declarations, should have a comment.  Don't
9633ff48bf5SDavid du Colombierspend a lot of time commenting executable code unless something unusual or
9643ff48bf5SDavid du Colombiersubtle is going on.
9653ff48bf5SDavid du Colombier
9663ff48bf5SDavid du Colombier<h3><a name="Naming"></a>Naming</h3>
9677dd7cddfSDavid du Colombier
9687dd7cddfSDavid du Colombier<p>
9697dd7cddfSDavid du ColombierUse fully spelled-out English words in names, rather than contractions.
9707dd7cddfSDavid du ColombierThis is most important for procedure and macro names, global variables and
9717dd7cddfSDavid du Colombierconstants, values of <b><tt>#define</tt></b> and <b><tt>enum</tt></b>,
9727dd7cddfSDavid du Colombier<b><tt>struct</tt></b> and other <b><tt>typedef</tt></b> names, and
9737dd7cddfSDavid du Colombierstructure member names, and for argument and variable names which have
9747dd7cddfSDavid du Colombieruninformative types like <b><tt>int</tt></b>.  It's not very important for
9757dd7cddfSDavid du Colombierarguments or local variables of distinctive types, or for local index or
9767dd7cddfSDavid du Colombiercount variables.
9777dd7cddfSDavid du Colombier
9787dd7cddfSDavid du Colombier<p>
9797dd7cddfSDavid du ColombierAvoid names that run English words together:
9807dd7cddfSDavid du Colombier"<b><tt>hpgl_compute_arc_center</tt></b>" is better than
9817dd7cddfSDavid du Colombier"<b><tt>hpgl_compute_arccenter</tt></b>".  However, for terms drawn from
9827dd7cddfSDavid du Colombiersome predefined source, like the names of PostScript operators, use a term
9837dd7cddfSDavid du Colombierin its well-known form (for instance, <b><tt>gs_setlinewidth</tt></b>
9847dd7cddfSDavid du Colombierrather than <b><tt>gs_set_line_width</tt></b>).
9857dd7cddfSDavid du Colombier
9867dd7cddfSDavid du Colombier<p>
9877dd7cddfSDavid du ColombierProcedures, variables, and structures visible outside a single
9887dd7cddfSDavid du Colombier<b><tt>.c</tt></b> file should generally have prefixes that indicate what
9897dd7cddfSDavid du Colombiersubsystem they belong to (in the case of Ghostscript, <b><tt>gs_</tt></b>
9907dd7cddfSDavid du Colombieror <b><tt>gx_</tt></b>).  This rule isn't followed very consistently.
9917dd7cddfSDavid du Colombier
9923ff48bf5SDavid du Colombier<h3><a name="Types"></a>Types</h3>
9937dd7cddfSDavid du Colombier
9947dd7cddfSDavid du Colombier<p>
9953ff48bf5SDavid du ColombierMany older structure names don't have <b><tt>_t</tt></b> on the end, but
9963ff48bf5SDavid du Colombierthis suffix should be used in all new code.  (The <b><tt>_s</tt></b>
9973ff48bf5SDavid du Colombierstructure name is needed only to satisfy some debuggers.  No code other than
9983ff48bf5SDavid du Colombierthe structure declaration should refer to it.)
9997dd7cddfSDavid du Colombier
10003ff48bf5SDavid du Colombier<p>
10013ff48bf5SDavid du ColombierDeclare structure types that contain pointers to other instances of
10023ff48bf5SDavid du Colombierthemselves like this:
10037dd7cddfSDavid du Colombier
10047dd7cddfSDavid du Colombier<blockquote>
10053ff48bf5SDavid du Colombier<b><tt>typedef struct xxx_s xxx_t;</tt></b><br>
10063ff48bf5SDavid du Colombier<b><tt>struct xxx_s {</tt></b><br>
10073ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;... members ...<br>
10083ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;<b><tt>xxx_t *</tt></b>ptr_member_name;<br>
10093ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;... members ...<br>
10103ff48bf5SDavid du Colombier<b><tt>};</tt></b>
10117dd7cddfSDavid du Colombier</blockquote>
10127dd7cddfSDavid du Colombier
10133ff48bf5SDavid du Colombier<p>
10143ff48bf5SDavid du ColombierIf, to maintain data abstraction and avoid including otherwise unnecessary
10153ff48bf5SDavid du Colombierheader files, you find that you want the type <b><tt>xxx_t</tt></b> to be
10163ff48bf5SDavid du Colombieravailable in a header file that doesn't include the definition of the
10173ff48bf5SDavid du Colombierstructure <b><tt>xxx_s</tt></b>, use this approach:
10187dd7cddfSDavid du Colombier
10197dd7cddfSDavid du Colombier<blockquote>
10203ff48bf5SDavid du Colombier<b><tt>#ifndef xxx_DEFINED</tt></b><br>
10213ff48bf5SDavid du Colombier<b><tt>#&nbsp;&nbsp;define xxx_DEFINED</tt></b><br>
10223ff48bf5SDavid du Colombier<b><tt>typedef struct xxx_s xxx_t;</tt></b><br>
10233ff48bf5SDavid du Colombier<b><tt>#endif</tt></b><br>
10243ff48bf5SDavid du Colombier<b><tt>struct xxx_s {</tt></b><br>
10253ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;... members ...<br>
10263ff48bf5SDavid du Colombier<b><tt>};</tt></b>
10277dd7cddfSDavid du Colombier</blockquote>
10287dd7cddfSDavid du Colombier
10293ff48bf5SDavid du Colombier<p>
10303ff48bf5SDavid du ColombierYou can then copy the first 4 lines in other header files.  (Don't ever
10313ff48bf5SDavid du Colombierinclude them in an executable code file.)
10327dd7cddfSDavid du Colombier
10333ff48bf5SDavid du Colombier<p>
10343ff48bf5SDavid du ColombierDon't bother using <b><tt>const</tt></b> for anything other than with
10353ff48bf5SDavid du Colombierpointers as described below.  However, in those places where it is necessary
10363ff48bf5SDavid du Colombierto cast a pointer of type <b><tt>const&nbsp;T&nbsp;*</tt></b> to type
10373ff48bf5SDavid du Colombier<b><tt>T&nbsp;*</tt></b>, always include a comment that explains why you are
10383ff48bf5SDavid du Colombier"breaking const".
10397dd7cddfSDavid du Colombier
10403ff48bf5SDavid du Colombier<h4>Pointers</h4>
10413ff48bf5SDavid du Colombier
10423ff48bf5SDavid du Colombier<p>
10433ff48bf5SDavid du ColombierUse <b><tt>const</tt></b> for pointer referents (that is,
10443ff48bf5SDavid du Colombier<b><tt>const&nbsp;T&nbsp;*</tt></b>) wherever possible and appropriate.
10453ff48bf5SDavid du Colombier
10463ff48bf5SDavid du Colombier<p>
10473ff48bf5SDavid du ColombierIf you find yourself wanting to use <b><tt>void&nbsp;*</tt></b>, try to
10483ff48bf5SDavid du Colombierfind an alternative using unions or (in the case of super- and subclasses)
10493ff48bf5SDavid du Colombiercasts, unless you're writing something like a memory manager that really
10503ff48bf5SDavid du Colombiertreats memory as opaque.
10513ff48bf5SDavid du Colombier
10523ff48bf5SDavid du Colombier<h3><a name="Procedures_style"></a>Procedures</h3>
10537dd7cddfSDavid du Colombier
10547dd7cddfSDavid du Colombier<p>
10557dd7cddfSDavid du ColombierIn general, don't create procedures that are private and only called from
10567dd7cddfSDavid du Colombierone place.  However, if a compound statement (especially an arm of a
10577dd7cddfSDavid du Colombierconditional) is too long for the eye easily to match its enclosing braces
10587dd7cddfSDavid du Colombier"<b><tt>{...}</tt></b>" -- that is, longer than 10 or 15 lines -- and it
10597dd7cddfSDavid du Colombierdoesn't use or set a lot of state held in outer local variables, it may be
10607dd7cddfSDavid du Colombiermore readable if you put it in a procedure.
10617dd7cddfSDavid du Colombier
10623ff48bf5SDavid du Colombier<h3>Miscellany</h3>
10633ff48bf5SDavid du Colombier
10643ff48bf5SDavid du Colombier<h4><a name="Local_variables"></a>Local variables</h4>
10657dd7cddfSDavid du Colombier
10667dd7cddfSDavid du Colombier<p>
10677dd7cddfSDavid du ColombierDon't assign new values to procedure parameters.  It makes debugging very
10687dd7cddfSDavid du Colombierconfusing when the parameter values printed for a procedure are not the
10697dd7cddfSDavid du Colombierones actually supplied by the caller.  Instead use a separate local
10707dd7cddfSDavid du Colombiervariable initialized to the value of the parameter.
10717dd7cddfSDavid du Colombier
10727dd7cddfSDavid du Colombier<p>
10737dd7cddfSDavid du ColombierIf a local variable is only assigned a value once, assign it that value at
10747dd7cddfSDavid du Colombierits declaration, if possible.  For example,
10757dd7cddfSDavid du Colombier
10767dd7cddfSDavid du Colombier<blockquote>
10777dd7cddfSDavid du Colombier<b><tt>int x = </tt></b>some expression <b><tt>;</tt></b>
10787dd7cddfSDavid du Colombier</blockquote>
10797dd7cddfSDavid du Colombier
10807dd7cddfSDavid du Colombier<p>
10817dd7cddfSDavid du Colombierrather than
10827dd7cddfSDavid du Colombier
10837dd7cddfSDavid du Colombier<blockquote>
10847dd7cddfSDavid du Colombier<b><tt>int x;</tt></b><br>
10857dd7cddfSDavid du Colombier...<br>
10867dd7cddfSDavid du Colombier<b><tt>x = </tt></b> some expression <b><tt>;</tt></b>
10877dd7cddfSDavid du Colombier</blockquote>
10887dd7cddfSDavid du Colombier
10897dd7cddfSDavid du Colombier<p>
10907dd7cddfSDavid du ColombierUse a local pointer variable like this to "narrow" pointer types:
10917dd7cddfSDavid du Colombier
10927dd7cddfSDavid du Colombier<blockquote>
10937dd7cddfSDavid du Colombier<b><tt>int</tt></b><br>
10947dd7cddfSDavid du Colombiersomeproc(... <b><tt>gx_device *dev</tt></b> ...)<br>
10957dd7cddfSDavid du Colombier<b><tt>{<br>
10967dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;gx_device_printer *const pdev = (gx_device_printer *)dev;</tt></b><br>
10977dd7cddfSDavid du Colombier&nbsp;&nbsp;&nbsp;...<br>
10987dd7cddfSDavid du Colombier<b><tt>}</tt></b>
10997dd7cddfSDavid du Colombier</blockquote>
11007dd7cddfSDavid du Colombier
1101*593dc095SDavid du Colombier<p>
1102*593dc095SDavid du ColombierDon't "shadow" a local variable or procedure parameter with an inner local
1103*593dc095SDavid du Colombiervariable of the same name.  I.e., don't do this:
1104*593dc095SDavid du Colombier
1105*593dc095SDavid du Colombier<blockquote>
1106*593dc095SDavid du Colombier<b><tt>int</tt></b><br>
1107*593dc095SDavid du Colombiersomeproc(... <b><tt>int x</tt></b> ...)<br>
1108*593dc095SDavid du Colombier<b><tt>{</tt></b><br>
1109*593dc095SDavid du Colombier&nbsp;&nbsp;&nbsp;...<br>
1110*593dc095SDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;int x;</tt></b><br>
1111*593dc095SDavid du Colombier&nbsp;&nbsp;&nbsp;...<br>
1112*593dc095SDavid du Colombier<b><tt>}</tt></b>
1113*593dc095SDavid du Colombier</blockquote>
1114*593dc095SDavid du Colombier
11153ff48bf5SDavid du Colombier<h4><a name="Compiler_warnings"></a>Compiler warnings</h4>
11167dd7cddfSDavid du Colombier
11177dd7cddfSDavid du Colombier<p>
11187dd7cddfSDavid du ColombierThe following section refers to the warnings produced by <b><tt>gcc</tt></b>:
11197dd7cddfSDavid du Colombieryour compiler may produce different ones.
11207dd7cddfSDavid du Colombier
11217dd7cddfSDavid du Colombier<p>
11227dd7cddfSDavid du ColombierIt's OK if compilation produces the following warnings:
11237dd7cddfSDavid du Colombier
11247dd7cddfSDavid du Colombier<ul>
11257dd7cddfSDavid du Colombier<li><b><tt>&lt;name&gt; might be used uninitialized in this function</tt></b>
11267dd7cddfSDavid du Colombier<li><b><tt>cast discards `const' from pointer target type</tt></b>
11277dd7cddfSDavid du Colombier</ul>
11287dd7cddfSDavid du Colombier
11297dd7cddfSDavid du Colombier<p>
11307dd7cddfSDavid du ColombierThe first of these often occurs because the compiler isn't aware of control
11317dd7cddfSDavid du Colombierflow restrictions that guarantee the variable will be initialized before
11327dd7cddfSDavid du Colombieruse: if it occurs in new code, check the code carefully, but don't worry
11337dd7cddfSDavid du Colombierabout the message.  The second is often unavoidable in code that initializes
11347dd7cddfSDavid du Colombieror frees a structure that is otherwise <b><tt>const</tt></b> during its
11357dd7cddfSDavid du Colombierlifetime.
11367dd7cddfSDavid du Colombier<p>
11377dd7cddfSDavid du Colombier
11387dd7cddfSDavid du ColombierDo work hard to eliminate all warnings other than these,
11397dd7cddfSDavid du Colombiersince they often indicate the possible presence of coding errors.
11407dd7cddfSDavid du ColombierIn particular, get rid of warnings about parameter passing or
11417dd7cddfSDavid du Colombierinitialization that discards <b><tt>const</tt></b>,
11427dd7cddfSDavid du Colombierby using explicit casts.
11437dd7cddfSDavid du Colombier
11443ff48bf5SDavid du Colombier<hr>
11453ff48bf5SDavid du Colombier
11463ff48bf5SDavid du Colombier<h2><a name="File_structuring"></a>File structuring</h2>
11473ff48bf5SDavid du Colombier
11483ff48bf5SDavid du Colombier<h3><a name="All_files"></a>All files</h3>
11493ff48bf5SDavid du Colombier
11503ff48bf5SDavid du Colombier<p>
11513ff48bf5SDavid du ColombierKeep file names within the "8.3" format for portability:
11523ff48bf5SDavid du Colombier<ul>
11533ff48bf5SDavid du Colombier<li>Use only letters, digits, dash, and underscore in file names.
11543ff48bf5SDavid du Colombier<li>Don't assume upper and lower case letters are distinct.
11553ff48bf5SDavid du Colombier<li>Put no more than 8 characters before the ".", if any.
11563ff48bf5SDavid du Colombier<li>If there is a ".", put between 1 and 3 characters after the ".".
11573ff48bf5SDavid du Colombier</ul>
11583ff48bf5SDavid du Colombier
11593ff48bf5SDavid du Colombier<p>
11603ff48bf5SDavid du ColombierFor files other than documentation files, use only lower case letters
11613ff48bf5SDavid du Colombierin the names; for HTML documentation files, capitalize the first letter.
11623ff48bf5SDavid du Colombier
11633ff48bf5SDavid du Colombier<p>
11643ff48bf5SDavid du ColombierEvery code file should start with comments containing
11653ff48bf5SDavid du Colombier
11663ff48bf5SDavid du Colombier<ol>
11673ff48bf5SDavid du Colombier<li>a copyright notice,
11683ff48bf5SDavid du Colombier<li>the name of the file in the form of an RCS Id:
11693ff48bf5SDavid du Colombier
11703ff48bf5SDavid du Colombier<blockquote><b><tt>
1171*593dc095SDavid du Colombier/* $<!-- -->Id: filename.ext $*/
11723ff48bf5SDavid du Colombier</tt></b></blockquote>
11733ff48bf5SDavid du Colombier
11743ff48bf5SDavid du Colombier<p>
11753ff48bf5SDavid du Colombier(using the comment convention appropriate to the language of the file), and
11763ff48bf5SDavid du Colombier
11773ff48bf5SDavid du Colombier<li>a summary, no more than one line, of what the file contains.
11783ff48bf5SDavid du Colombier</ol>
11793ff48bf5SDavid du Colombier
11803ff48bf5SDavid du Colombier<p>
11813ff48bf5SDavid du ColombierIf you create a file by copying the beginning of another file, be sure to
11823ff48bf5SDavid du Colombierupdate the copyright year and change the file name.
11833ff48bf5SDavid du Colombier
11843ff48bf5SDavid du Colombier<h3><a name="Makefiles"></a>Makefiles</h3>
11853ff48bf5SDavid du Colombier
11863ff48bf5SDavid du Colombier<p>
11873ff48bf5SDavid du ColombierUse the extension <b><tt>.mak</tt></b> for makefiles.
11883ff48bf5SDavid du Colombier
11893ff48bf5SDavid du Colombier<p>
11903ff48bf5SDavid du ColombierFor each
11913ff48bf5SDavid du Colombier
11923ff48bf5SDavid du Colombier<blockquote><b><tt>
11933ff48bf5SDavid du Colombier#include "xxx.h"
11943ff48bf5SDavid du Colombier</tt></b></blockquote>
11953ff48bf5SDavid du Colombier
11963ff48bf5SDavid du Colombier<p>
11973ff48bf5SDavid du Colombiermake sure there is a dependency on <b><tt>$(xxx_h)</tt></b> in the
11983ff48bf5SDavid du Colombiermakefile.  If xxx ends with a "<b><tt>_</tt></b>", this rule still holds,
11993ff48bf5SDavid du Colombierso that if you code
12003ff48bf5SDavid du Colombier
12013ff48bf5SDavid du Colombier<blockquote><b><tt>
12023ff48bf5SDavid du Colombier#include "math_.h"
12033ff48bf5SDavid du Colombier</tt></b></blockquote>
12043ff48bf5SDavid du Colombier
12053ff48bf5SDavid du Colombier<p>
12063ff48bf5SDavid du Colombierthe makefile must contain a dependency on "<b><tt>$(math__h)</tt></b>"
12073ff48bf5SDavid du Colombier(note the two underscores "<b><tt>__</tt></b>").
12083ff48bf5SDavid du Colombier
12093ff48bf5SDavid du Colombier<p>
12103ff48bf5SDavid du ColombierList the dependencies bottom-to-top, like the <b><tt>#include</tt></b>
12113ff48bf5SDavid du Colombierstatements themselves; within each level, list them alphabetically.  Do
12123ff48bf5SDavid du Colombierthis also with <b><tt>#include</tt></b> statements themselves whenever
12133ff48bf5SDavid du Colombierpossible (but sometimes there are inter-header dependencies that require
12143ff48bf5SDavid du Colombierbending this rule).
12153ff48bf5SDavid du Colombier
12163ff48bf5SDavid du Colombier<p>
12173ff48bf5SDavid du ColombierFor compatibility with the build utilities on OpenVMS, always put a space
12183ff48bf5SDavid du Colombierbefore the colon that separates the target(s) of a rule from the dependents.
12193ff48bf5SDavid du Colombier
12203ff48bf5SDavid du Colombier<h3><a name="General_C_code"></a>General C code</h3>
12213ff48bf5SDavid du Colombier
12223ff48bf5SDavid du Colombier<p>
12233ff48bf5SDavid du ColombierList <b><tt>#include</tt></b> statements from "bottom" to "top", that is,
12243ff48bf5SDavid du Colombierin the following order:
12253ff48bf5SDavid du Colombier
12263ff48bf5SDavid du Colombier<blockquote><ol>
12273ff48bf5SDavid du Colombier<li>System includes (<b><tt>"xxx_.h"</tt></b>)
12283ff48bf5SDavid du Colombier<li><b><tt>gs*.h</tt></b>
12293ff48bf5SDavid du Colombier<li><b><tt>gx*.h</tt></b> (yes, <b><tt>gs</tt></b> and <b><tt>gx</tt></b>
12303ff48bf5SDavid du Colombierare in the wrong order.)
12313ff48bf5SDavid du Colombier<li><b><tt>s*.h</tt></b>
12323ff48bf5SDavid du Colombier<li><b><tt>i*.h</tt></b> (or other interpreter headers that don't start
12333ff48bf5SDavid du Colombierwith "<b><tt>i</tt></b>")
12343ff48bf5SDavid du Colombier</ol></blockquote>
12353ff48bf5SDavid du Colombier
12363ff48bf5SDavid du Colombier<h3><a name="Headers"></a>Headers (<b><tt>.h</tt></b> files)</h3>
12373ff48bf5SDavid du Colombier
12383ff48bf5SDavid du Colombier<p>
12393ff48bf5SDavid du ColombierIn header files, always use the following at the beginning of a header file
12403ff48bf5SDavid du Colombierto prevent double inclusion:
12413ff48bf5SDavid du Colombier
12423ff48bf5SDavid du Colombier<blockquote>
12433ff48bf5SDavid du Colombier{{ Copyright notice etc. }}<br><br>
12443ff48bf5SDavid du Colombier
12453ff48bf5SDavid du Colombier<b><tt>#ifndef </tt></b>&lt;filename&gt;<b><tt>_INCLUDED</tt></b><br>
12463ff48bf5SDavid du Colombier<b><tt>#define </tt></b>&lt;filename&gt;<b><tt>_INCLUDED</tt></b><br><br>
12473ff48bf5SDavid du Colombier
12483ff48bf5SDavid du Colombier{{ The contents of the file }}<br><br>
12493ff48bf5SDavid du Colombier
12503ff48bf5SDavid du Colombier<b><tt>#endif /* </tt></b>&lt;filename&gt;<b><tt>_INCLUDED */</tt></b>
12513ff48bf5SDavid du Colombier</blockquote>
12523ff48bf5SDavid du Colombier
12533ff48bf5SDavid du Colombier<p>
12543ff48bf5SDavid du ColombierThe header file is the first place that a reader goes for
12553ff48bf5SDavid du Colombierinformation about procedures, structures, constants, etc., so ensure that
12563ff48bf5SDavid du Colombierevery procedure and structure has a comment that says what it does.  Divide
12573ff48bf5SDavid du Colombierprocedures into meaningful groups set off by some distinguished form of
12583ff48bf5SDavid du Colombiercomment.
12593ff48bf5SDavid du Colombier
12603ff48bf5SDavid du Colombier<h3><a name="Source"></a>Source (<b><tt>.c</tt></b> files)</h3>
12613ff48bf5SDavid du Colombier
12623ff48bf5SDavid du Colombier<p>
12633ff48bf5SDavid du ColombierAfter the initial comments, arrange C files in the following order:
12643ff48bf5SDavid du Colombier
12653ff48bf5SDavid du Colombier<blockquote><ol>
12663ff48bf5SDavid du Colombier<li><b><tt>#include</tt></b> statements
12673ff48bf5SDavid du Colombier<li>Exported data declarations
12683ff48bf5SDavid du Colombier<li>Explicit externs (if necessary)
12693ff48bf5SDavid du Colombier<li>Forward declarations of procedures
12703ff48bf5SDavid du Colombier<li>Private data declarations
12713ff48bf5SDavid du Colombier<li>Exported procedures
12723ff48bf5SDavid du Colombier<li>Private procedures
12733ff48bf5SDavid du Colombier</ol></blockquote>
12743ff48bf5SDavid du Colombier
12753ff48bf5SDavid du Colombier<p>
12763ff48bf5SDavid du ColombierBe flexible about the order of the declarations if necessary to improve
12773ff48bf5SDavid du Colombierreadability.  Many older files don't follow this order, often without good
12783ff48bf5SDavid du Colombierreason.
12793ff48bf5SDavid du Colombier
12803ff48bf5SDavid du Colombier<hr>
12813ff48bf5SDavid du Colombier
12823ff48bf5SDavid du Colombier<h2><a name="Conventions"></a>Ghostscript conventions</h2>
12833ff48bf5SDavid du Colombier
12843ff48bf5SDavid du Colombier<h3><a name="Specific_names"></a>Specific names</h3>
12853ff48bf5SDavid du Colombier
12863ff48bf5SDavid du Colombier<p>
12873ff48bf5SDavid du ColombierThe Ghostscript code uses certain names consistently for certain kinds of
12883ff48bf5SDavid du Colombiervalues.  Some of the commonest and least obvious are these two:
12893ff48bf5SDavid du Colombier
12903ff48bf5SDavid du Colombier<h4><a name="code"></a><b><tt>code</tt></b></h4>
12913ff48bf5SDavid du Colombier
12923ff48bf5SDavid du Colombier<blockquote>
12933ff48bf5SDavid du ColombierA value to be returned from a procedure:
12943ff48bf5SDavid du Colombier
12953ff48bf5SDavid du Colombier<table cellpadding=0 cellspacing=0>
12963ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>&lt; 0
12973ff48bf5SDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;&nbsp;
12983ff48bf5SDavid du Colombier	<td>An error code defined in
12993ff48bf5SDavid du Colombier<a href="../src/gserrors.h">gserrors.h</a>
1300*593dc095SDavid du Colombier(or <a href="../src/ierrors.h">ierrors.h</a>)
13013ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>0
13023ff48bf5SDavid du Colombier	<td>&nbsp;
13033ff48bf5SDavid du Colombier	<td>Normal return
13043ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>&gt; 0
13053ff48bf5SDavid du Colombier	<td>&nbsp;
13063ff48bf5SDavid du Colombier	<td>A non-standard but successful return (which must be documented, preferably with the procedure's prototype)
13073ff48bf5SDavid du Colombier</table>
13083ff48bf5SDavid du Colombier
13093ff48bf5SDavid du Colombier</blockquote>
13103ff48bf5SDavid du Colombier
13113ff48bf5SDavid du Colombier<h4><a name="status"></a><b><tt>status</tt></b></h4>
13123ff48bf5SDavid du Colombier
13133ff48bf5SDavid du Colombier<blockquote>
13143ff48bf5SDavid du ColombierA value returned from a stream procedure:
13153ff48bf5SDavid du Colombier
13163ff48bf5SDavid du Colombier<table cellpadding=0 cellspacing=0>
13173ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>&lt; 0
13183ff48bf5SDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;&nbsp;
13193ff48bf5SDavid du Colombier	<td>An exceptional condition as defined in
13203ff48bf5SDavid du Colombier<a href="../src/scommon.h">scommon.h</a>
13213ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>0
13223ff48bf5SDavid du Colombier	<td>&nbsp;
13233ff48bf5SDavid du Colombier	<td>Normal return (or, from the "<b><tt>process</tt></b>" procedure, means that more input is needed)
13243ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>1
13253ff48bf5SDavid du Colombier	<td>&nbsp;
13263ff48bf5SDavid du Colombier	<td>More output space is needed (from the "<b><tt>process</tt></b>" procedure)
13273ff48bf5SDavid du Colombier</table>
13283ff48bf5SDavid du Colombier</blockquote>
13293ff48bf5SDavid du Colombier
13303ff48bf5SDavid du Colombier<h3><a name="Structure_type_descriptors"></a>Structure type descriptors</h3>
13313ff48bf5SDavid du Colombier
13323ff48bf5SDavid du Colombier<p>
13333ff48bf5SDavid du ColombierThe Ghostscript memory manager requires run-time type information for every
13343ff48bf5SDavid du Colombierstructure.  (We don't document this in detail here: see the <a
13353ff48bf5SDavid du Colombierhref="Develop.htm#Structure_descriptors">Structure descriptors</a> section
13363ff48bf5SDavid du Colombierof the developer documentation for details.)  Putting the descriptor for a
13373ff48bf5SDavid du Colombierstructure next to the structure definition will help keep the two
13383ff48bf5SDavid du Colombierconsistent, so immediately after the definition of a structure
13393ff48bf5SDavid du Colombier<b><tt>xxx_s</tt></b>, define its structure descriptor:
13403ff48bf5SDavid du Colombier
13413ff48bf5SDavid du Colombier<blockquote>
13423ff48bf5SDavid du Colombier<b><tt>struct xxx_s {</tt></b><br>
13433ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;... members ...<br>
13443ff48bf5SDavid du Colombier<b><tt>};</tt></b><br>
13453ff48bf5SDavid du Colombier<b><tt>#define private_st_xxx()&nbsp;&nbsp;/* in </tt></b>&lt;filename&gt;<tt><b>.c */\</tt></b><br>
13463ff48bf5SDavid du Colombier<b><tt>&nbsp;&nbsp;gs_private_st_</tt></b>&lt;whatever&gt;<b><tt>(st_xxx, xxx_t,\</tt></b><br>
13473ff48bf5SDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;"xxx_t", xxx_enum_ptrs, xxx_reloc_ptrs,\</tt></b><br>
13483ff48bf5SDavid du Colombier<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;</tt></b>... additional parameters as needed ...<b><tt>)</tt></b>
13493ff48bf5SDavid du Colombier</blockquote>
13503ff48bf5SDavid du Colombier
13513ff48bf5SDavid du Colombier<p>
13523ff48bf5SDavid du ColombierThe file that implements operations on this structure
13533ff48bf5SDavid du Colombier(&lt;filename&gt;<b><tt>.c</tt></b>) should then include, near the
13543ff48bf5SDavid du Colombierbeginning, the line:
13553ff48bf5SDavid du Colombier
13563ff48bf5SDavid du Colombier<blockquote>
13573ff48bf5SDavid du Colombier<b><tt>private_st_xxx();</tt></b>
13583ff48bf5SDavid du Colombier</blockquote>
13593ff48bf5SDavid du Colombier
13603ff48bf5SDavid du Colombier<p>
13613ff48bf5SDavid du ColombierIn much existing code, structure descriptors are declared as
13623ff48bf5SDavid du Colombier<b><tt>public</tt></b>, which allows clients to allocate instances of the
13633ff48bf5SDavid du Colombierstructure directly.  We now consider this bad design.  Instead, structure
13643ff48bf5SDavid du Colombierdescriptors should always be <b><tt>private</tt></b>; the implementation
13653ff48bf5SDavid du Colombierfile should provide one or more procedures for allocating instances, e.g.,
13663ff48bf5SDavid du Colombier
13673ff48bf5SDavid du Colombier<blockquote>
13683ff48bf5SDavid du Colombier<b><tt>xxx_t *gs_xxx_alloc(P1(gs_memory_t *mem));</tt></b>
13693ff48bf5SDavid du Colombier</blockquote>
13703ff48bf5SDavid du Colombier
13713ff48bf5SDavid du Colombier<p>
13723ff48bf5SDavid du ColombierIf it is necessary to make a structure descriptor public, it should be
13733ff48bf5SDavid du Colombierdeclared in its clients as
13743ff48bf5SDavid du Colombier
13753ff48bf5SDavid du Colombier<blockquote>
13763ff48bf5SDavid du Colombier<b><tt>extern_st(st_xxx);</tt></b>
13773ff48bf5SDavid du Colombier</blockquote>
13783ff48bf5SDavid du Colombier
13793ff48bf5SDavid du Colombier<h3><a name="Objects"></a>"Objects"</h3>
13803ff48bf5SDavid du Colombier
13813ff48bf5SDavid du Colombier<p>
13823ff48bf5SDavid du ColombierGhostscript makes heavy use of object-oriented constructs, including
13833ff48bf5SDavid du Colombieranalogues of classes, instances, subclassing, and class-associated
13843ff48bf5SDavid du Colombierprocedures.  However, these constructs are implemented in C rather than C++,
13853ff48bf5SDavid du Colombierfor two reasons:
13863ff48bf5SDavid du Colombier
13873ff48bf5SDavid du Colombier<ul>
13883ff48bf5SDavid du Colombier
13893ff48bf5SDavid du Colombier<li>The first Ghostscript code was written in 1986, long before C++ was
13903ff48bf5SDavid du Colombiercodified or was well supported by tools.  Even today, C++ tools rarely
13913ff48bf5SDavid du Colombiersupport C++ as well as C tools support C.
13923ff48bf5SDavid du Colombier
13933ff48bf5SDavid du Colombier<li>C++ imposes its own implementations for virtual procedures, inheritance,
13943ff48bf5SDavid du Colombierrun-time type information, and (to some extent) memory management.
13953ff48bf5SDavid du ColombierGhostscript requires use of its own memory manager, and also sometimes
13963ff48bf5SDavid du Colombierrequires the ability to change the virtual procedures of an object
13973ff48bf5SDavid du Colombierdynamically.
13983ff48bf5SDavid du Colombier
13993ff48bf5SDavid du Colombier</ul>
14003ff48bf5SDavid du Colombier
14013ff48bf5SDavid du Colombier<h4>Classes</h4>
14023ff48bf5SDavid du Colombier
14033ff48bf5SDavid du Colombier<p>
14043ff48bf5SDavid du ColombierThe source code representation of a class is simply a
14053ff48bf5SDavid du Colombier<b><tt>typedef</tt></b> for a C <b><tt>struct</tt></b>.  See <a
14063ff48bf5SDavid du Colombierhref="C-style.htm#Structures">Structures</a>, above, for details.
14073ff48bf5SDavid du Colombier
14083ff48bf5SDavid du Colombier<h4>Procedures</h4>
14093ff48bf5SDavid du Colombier
14103ff48bf5SDavid du Colombier<p>
14113ff48bf5SDavid du ColombierGhostscript has no special construct for non-virtual procedures associated
14123ff48bf5SDavid du Colombierwith a class.  In some cases, the <b><tt>typedef</tt></b> for the class is
14133ff48bf5SDavid du Colombierin a header file but the <b><tt>struct</tt></b> declaration is in the
14143ff48bf5SDavid du Colombierimplementation code file: this provides an extra level of opaqueness, since
14153ff48bf5SDavid du Colombierclients then can't see the representation and must make all accesses through
14163ff48bf5SDavid du Colombierprocedures.  You should use this approach in new code, if it doesn't
14173ff48bf5SDavid du Colombierincrease the size of the code too much or require procedure calls for very
14183ff48bf5SDavid du Colombierheavily used accesses.
14193ff48bf5SDavid du Colombier
14203ff48bf5SDavid du Colombier<p>
14213ff48bf5SDavid du ColombierGhostscript uses three different approaches for storing and accessing
14223ff48bf5SDavid du Colombiervirtual procedures, plus a fourth one that is recommended but not currently
14233ff48bf5SDavid du Colombierused.  For exposition, we assume the class (type) is named
14243ff48bf5SDavid du Colombier<b><tt>xxx_t</tt></b>, it has a virtual procedure
14253ff48bf5SDavid du Colombier<b><tt>void&nbsp;(*virtu)(P1(xxx_t&nbsp;*))</tt></b>, and we have a variable
14263ff48bf5SDavid du Colombierdeclared as <b><tt>xxx_t&nbsp;*pxx</tt></b>.
14273ff48bf5SDavid du Colombier
14283ff48bf5SDavid du Colombier<ol>
14293ff48bf5SDavid du Colombier
14303ff48bf5SDavid du Colombier<li>The procedures are stored in a separate, constant structure of type
14313ff48bf5SDavid du Colombier<b><tt>xxx_procs</tt></b>, of which <b><tt>virtu</tt></b> is a member.  The
14323ff48bf5SDavid du Colombierstructure definition of <b><tt>xxx_t</tt></b> includes a member defined as
14333ff48bf5SDavid du Colombier<b><tt>const&nbsp;xxx_procs&nbsp;*procs</tt></b> (always named
14343ff48bf5SDavid du Colombier<b><tt>procs</tt></b>).  The construct for calling the virtual procedure is
14353ff48bf5SDavid du Colombier<b><tt>pxx->procs->virtu(pxx)</tt></b>.
14363ff48bf5SDavid du Colombier
14373ff48bf5SDavid du Colombier<li>The procedures are defined in a structure of type
14383ff48bf5SDavid du Colombier<b><tt>xxx_procs</tt></b> as above.  The structure definition of
14393ff48bf5SDavid du Colombier<b><tt>xxx_t</tt></b> includes a member defined as
14403ff48bf5SDavid du Colombier<b><tt>xxx_procs&nbsp;procs</tt></b> (always named <b><tt>procs</tt></b>).
14413ff48bf5SDavid du ColombierThe construct for calling the virtual procedure is
14423ff48bf5SDavid du Colombier<b><tt>pxx->procs.virtu(pxx)</tt></b>.
14433ff48bf5SDavid du Colombier
14443ff48bf5SDavid du Colombier<li>The procedures are not defined in a separate structure: each procedure
14453ff48bf5SDavid du Colombieris a separate member of <b><tt>xxx_t</tt></b>.  The construct for calling
14463ff48bf5SDavid du Colombierthe virtual procedure is <b><tt>pxx->virtu(pxx)</tt></b>.
14473ff48bf5SDavid du Colombier
14483ff48bf5SDavid du Colombier<li>The procedures are defined in a structure of type
14493ff48bf5SDavid du Colombier<b><tt>xxx_procs</tt></b> as above.  The structure definition of
14503ff48bf5SDavid du Colombier<b><tt>xxx_t</tt></b> includes a member defined as
14513ff48bf5SDavid du Colombier<b><tt>xxx_procs&nbsp;procs[1]</tt></b> (always named
14523ff48bf5SDavid du Colombier<b><tt>procs</tt></b>).  The construct for calling the virtual procedure is
14533ff48bf5SDavid du Colombieragain <b><tt>pxx->procs->virtu(pxx)</tt></b>.
14543ff48bf5SDavid du Colombier
14553ff48bf5SDavid du Colombier</ol>
14563ff48bf5SDavid du Colombier
14573ff48bf5SDavid du Colombier<p>
14583ff48bf5SDavid du ColombierNote that in approach 1, the procedures are in a shared constant structure;
14593ff48bf5SDavid du Colombierin approaches 2 - 4, they are in a per-instance structure that can be
14603ff48bf5SDavid du Colombierchanged dynamically, which is sometimes important.
14613ff48bf5SDavid du Colombier
14623ff48bf5SDavid du Colombier<p>
14633ff48bf5SDavid du ColombierIn the present Ghostscript code, approach 1 is most common, followed by 2
14643ff48bf5SDavid du Colombierand 3; 4 is not used at all.  For new code, you should use 1 or 4: that way,
14653ff48bf5SDavid du Colombierall virtual procedure calls have the same form, regardless of whether the
14663ff48bf5SDavid du Colombierprocedures are shared and constant or per-instance and mutable.
14673ff48bf5SDavid du Colombier
14683ff48bf5SDavid du Colombier<h4>Subclassing</h4>
14693ff48bf5SDavid du Colombier
14703ff48bf5SDavid du Colombier<p>
14713ff48bf5SDavid du ColombierGhostscript's class mechanism allows for subclasses that can add data
14723ff48bf5SDavid du Colombiermembers, or can add procedure members if approach 1 or 3 (above) is used.
14733ff48bf5SDavid du ColombierSince C doesn't support subclassing, we use a convention to accomplish it.
14743ff48bf5SDavid du ColombierIn the example below, <b><tt>gx_device</tt></b> is the root class; it has a
14753ff48bf5SDavid du Colombiersubclass <b><tt>gx_device_forward</tt></b>, which in turn has a subclass
14763ff48bf5SDavid du Colombier<b><tt>gx_device_null</tt></b>.  First we define a macro for all the members
14773ff48bf5SDavid du Colombierof the root class, and the root class type.  (As for structures in general,
14783ff48bf5SDavid du Colombierclasses need a structure descriptor, as discussed in <a
14793ff48bf5SDavid du Colombierhref="#Structures">Structures</a> above: we include these in the examples
14803ff48bf5SDavid du Colombierbelow.)
14813ff48bf5SDavid du Colombier
14823ff48bf5SDavid du Colombier<blockquote><b><tt>
14833ff48bf5SDavid du Colombier#define gx_device_common\<br>
14843ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;type1 member1;\<br>
14853ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;</tt></b>...<b><tt><br>
14863ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;typeN memberN<br>
14873ff48bf5SDavid du Colombier<br>
14883ff48bf5SDavid du Colombiertypedef struct gx_device_s {<br>
14893ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device_common;<br>
14903ff48bf5SDavid du Colombier} gx_device;<br>
14913ff48bf5SDavid du Colombier<br>
14923ff48bf5SDavid du Colombier#define private_st_gx_device()&nbsp;&nbsp;/* in gsdevice.c */\<br>
14933ff48bf5SDavid du Colombier&nbsp;&nbsp;gs_private_st_</tt></b>&lt;whatever&gt;<b><tt>(st_gx_device, gx_device,\<br>
14943ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;"gx_device", device_enum_ptrs, device_reloc_ptrs,\<br>
14953ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;</tt></b>... additional parameters as needed ...<b><tt>)</tt></b>
14963ff48bf5SDavid du Colombier</tt></b></blockquote>
14973ff48bf5SDavid du Colombier
14983ff48bf5SDavid du Colombier<p>
14993ff48bf5SDavid du ColombierWe then define a similar macro and type for the subclass.
15003ff48bf5SDavid du Colombier
15013ff48bf5SDavid du Colombier<blockquote><b><tt>
15023ff48bf5SDavid du Colombier#define gx_device_forward_common\<br>
15033ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device_common;\<br>
15043ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device *target<br>
15053ff48bf5SDavid du Colombier<br>
15063ff48bf5SDavid du Colombiertypedef struct gx_device_forward_s {<br>
15073ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device_forward_common;<br>
15083ff48bf5SDavid du Colombier} gx_device_forward;<br>
15093ff48bf5SDavid du Colombier<br>
15103ff48bf5SDavid du Colombier#define private_st_device_forward()&nbsp;&nbsp;/* in gsdevice.c */\<br>
15113ff48bf5SDavid du Colombier&nbsp;&nbsp;gs_private_st_suffix_add1(st_device_forward, gx_device_forward,\<br>
15123ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;"gx_device_forward", device_forward_enum_ptrs, device_forward_reloc_ptrs,\<br>
15133ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device, target)
15143ff48bf5SDavid du Colombier</tt></b></blockquote>
15153ff48bf5SDavid du Colombier
15163ff48bf5SDavid du Colombier<p>
15173ff48bf5SDavid du ColombierFinally, we define a leaf class, which doesn't need a macro because we don't
15183ff48bf5SDavid du Colombiercurrently subclass it.  (We can create the macro later if needed, with no
15193ff48bf5SDavid du Colombierchanges anywhere else.)  In this particular case, the leaf class has no
15203ff48bf5SDavid du Colombieradditional data members, but it could have some.
15213ff48bf5SDavid du Colombier
15223ff48bf5SDavid du Colombier<blockquote><b><tt>
15233ff48bf5SDavid du Colombiertypedef struct gx_device_null_s {<br>
15243ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device_forward_common;<br>
15253ff48bf5SDavid du Colombier};<br>
15263ff48bf5SDavid du Colombier<br>
15273ff48bf5SDavid du Colombier#define private_st_device_null()&nbsp;&nbsp;/* in gsdevice.c */\<br>
15283ff48bf5SDavid du Colombier&nbsp;&nbsp;gs_private_st_suffix_add0_local(st_device_null, gx_device_null,\<br>
15293ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;"gx_device_null", device_null_enum_ptrs, device_null_reloc_ptrs,\<br>
15303ff48bf5SDavid du Colombier&nbsp;&nbsp;&nbsp;&nbsp;gx_device_forward)
15313ff48bf5SDavid du Colombier</tt></b></blockquote>
15323ff48bf5SDavid du Colombier
15333ff48bf5SDavid du Colombier<p>
15343ff48bf5SDavid du ColombierNote that the above example is <strong>not</strong> the actual definition of
15353ff48bf5SDavid du Colombierthe <b><tt>gx_device</tt></b> structure type: the actual type has some
15363ff48bf5SDavid du Colombieradditional complications because it has a finalization procedure.  See <a
15373ff48bf5SDavid du Colombierhref="../src/gxdevcli.h">src/gxdevcli.h</a> for the details.
15383ff48bf5SDavid du Colombier
15393ff48bf5SDavid du Colombier<p>
15403ff48bf5SDavid du ColombierIf you add members to a root class (such as <b><tt>gx_device</tt></b> in
15413ff48bf5SDavid du Colombierthis example), or change existing members, do this in the
15423ff48bf5SDavid du Colombier<b><tt>gx_device_common</tt></b> macro, not the <b><tt>gx_device</tt></b>
15433ff48bf5SDavid du Colombierstructure definition.  Similarly, to change the
15443ff48bf5SDavid du Colombier<b><tt>gx_device_forward</tt></b> class, modify the
15453ff48bf5SDavid du Colombier<b><tt>gx_device_forward_common</tt></b> macro, not the structure
15463ff48bf5SDavid du Colombierdefinition.  Only change the structure definition if the class is a leaf
15473ff48bf5SDavid du Colombierclass (one with no <b><tt>_common</tt></b> macro and no possibility of
15483ff48bf5SDavid du Colombiersubclassing), like <b><tt>gx_device_null</tt></b>.
15493ff48bf5SDavid du Colombier
15503ff48bf5SDavid du Colombier<h3><a name="Error_handling"></a>Error handling</h3>
15513ff48bf5SDavid du Colombier
15523ff48bf5SDavid du Colombier<p>
15533ff48bf5SDavid du ColombierEvery caller should check for error returns and, in general, propagate them
15543ff48bf5SDavid du Colombierto <b>its</b> callers.  By convention, nearly every procedure returns an
15553ff48bf5SDavid du Colombier<b><tt>int</tt></b> to indicate the outcome of the call:
15563ff48bf5SDavid du Colombier
15573ff48bf5SDavid du Colombier<blockquote><table cellpadding=0 cellspacing=0>
15583ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>&lt; 0
15593ff48bf5SDavid du Colombier	<td>&nbsp;&nbsp;&nbsp;&nbsp;
15603ff48bf5SDavid du Colombier	<td>Error return
15613ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>0
15623ff48bf5SDavid du Colombier	<td>&nbsp;
15633ff48bf5SDavid du Colombier	<td>Normal return
15643ff48bf5SDavid du Colombier<tr valign=top>	<td align=right>&gt; 0
15653ff48bf5SDavid du Colombier	<td>&nbsp;
15663ff48bf5SDavid du Colombier	<td>Non-error return other than the normal case
15673ff48bf5SDavid du Colombier</table></blockquote>
15683ff48bf5SDavid du Colombier
15693ff48bf5SDavid du Colombier<p>
15703ff48bf5SDavid du ColombierTo make a procedure generate an error and return it, as opposed to
15713ff48bf5SDavid du Colombierpropagating an error generated by a lower procedure, you should use
15723ff48bf5SDavid du Colombier
15733ff48bf5SDavid du Colombier<blockquote>
15743ff48bf5SDavid du Colombier<b><tt>return_error(</tt></b><em>error_number</em><b><tt>);</tt></b>
15753ff48bf5SDavid du Colombier</blockquote>
15763ff48bf5SDavid du Colombier
15773ff48bf5SDavid du Colombier<p>
15783ff48bf5SDavid du ColombierSometimes it is more convenient to generate the error in one place and
15793ff48bf5SDavid du Colombierreturn it in another.  In this case, you should use
15803ff48bf5SDavid du Colombier
15813ff48bf5SDavid du Colombier<blockquote>
15823ff48bf5SDavid du Colombier<b><tt>code = gs_note_error(</tt></b><em>error_number</em><b><tt>);</tt></b><br>
15833ff48bf5SDavid du Colombier...<br>
15843ff48bf5SDavid du Colombier<b><tt>return code;</tt></b>
15853ff48bf5SDavid du Colombier</blockquote>
15863ff48bf5SDavid du Colombier
15873ff48bf5SDavid du Colombier<p>
15883ff48bf5SDavid du ColombierIn executables built for debugging, the <b><tt>-E</tt></b> (or
15893ff48bf5SDavid du Colombier<b><tt>-Z#</tt></b>) command line switch causes <b><tt>return_error</tt></b>
15903ff48bf5SDavid du Colombierand <b><tt>gs_note_error</tt></b> to print the error number and the source
15913ff48bf5SDavid du Colombierfile and line: this is often helpful for identifying the original cause of
15923ff48bf5SDavid du Colombieran error.
15933ff48bf5SDavid du Colombier
15943ff48bf5SDavid du Colombier<p>
15953ff48bf5SDavid du ColombierSee the file <a href="../src/gserrors.h">src/gserrors.h</a> for the error
15963ff48bf5SDavid du Colombierreturn codes used by the graphics library, most of which correspond directly
15973ff48bf5SDavid du Colombierto PostScript error conditions.
15983ff48bf5SDavid du Colombier
15997dd7cddfSDavid du Colombier<!-- [2.0 end contents] ==================================================== -->
16007dd7cddfSDavid du Colombier
16017dd7cddfSDavid du Colombier<!-- [3.0 begin visible trailer] =========================================== -->
16027dd7cddfSDavid du Colombier<hr>
16037dd7cddfSDavid du Colombier
16043ff48bf5SDavid du Colombier<p>
16053ff48bf5SDavid du Colombier<small>Copyright &copy; 1996, 1997, 1998 Aladdin Enterprises.
16063ff48bf5SDavid du ColombierCopyright &copy; 2001 artofcode LLC.
16073ff48bf5SDavid du ColombierAll rights reserved.</small>
16087dd7cddfSDavid du Colombier
16097dd7cddfSDavid du Colombier<p>
16103ff48bf5SDavid du Colombier<small>This file is part of AFPL Ghostscript.  See the <a
16113ff48bf5SDavid du Colombierhref="Public.htm">Aladdin Free Public License</a> (the "License") for full
16123ff48bf5SDavid du Colombierdetails of the terms of using, copying, modifying, and redistributing AFPL
16133ff48bf5SDavid du ColombierGhostscript.</small>
16147dd7cddfSDavid du Colombier
16153ff48bf5SDavid du Colombier<p>
1616*593dc095SDavid du Colombier<small>Ghostscript version 8.53, 20 October 2005
16177dd7cddfSDavid du Colombier
16187dd7cddfSDavid du Colombier<!-- [3.0 end visible trailer] ============================================= -->
16197dd7cddfSDavid du Colombier
16207dd7cddfSDavid du Colombier</body>
16217dd7cddfSDavid du Colombier</html>
1622