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 int x = 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 *</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 ... 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 xxx_s *</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 = 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->func(...)</tt></b>. Some old code uses explicit indirection, 4353ff48bf5SDavid du Colombier<b><tt>(*ptr->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>&&</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>/* falls through */</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 gs_error_rangecheck</tt></b> or 4733ff48bf5SDavid du Colombier<b><tt>return 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 (code < 0) return 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 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 -bad -nbap -nsob -br -ce -cli4 -npcs -ncs \<br> 6767dd7cddfSDavid du Colombier -i4 -di0 -psl -lp -lps 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 xyz</tt></b><br> 696*593dc095SDavid du Colombier<b><tt># define xyz 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 <b><tt>=</tt></b> value<b><tt>;</tt></b><br> 7073ff48bf5SDavid du Colombiervar1 <b><tt>=</tt></b> var2 <b><tt>=</tt></b> value<b><tt>;</tt></b><br> 7083ff48bf5SDavid du Colombiervar1 <b><tt>=</tt></b><br> 7093ff48bf5SDavid du Colombier value<b><tt>;</tt></b><br> 7103ff48bf5SDavid du Colombiervar1 <b><tt>=</tt></b><br> 7113ff48bf5SDavid du Colombier var2 <b><tt>=</tt></b> value<b><tt>;</tt></b><br> 7123ff48bf5SDavid du Colombiervar1 <b><tt>=</tt></b> var2 <b><tt>=</tt></b><br> 7133ff48bf5SDavid du Colombier 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 <b><tt>=</tt></b><br> 7213ff48bf5SDavid du Colombiervar2 <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 ... declarations ...<br> 7307dd7cddfSDavid du Colombier {{ blank line if any declarations above }}<br> 7317dd7cddfSDavid du Colombier ... 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 ... declarations ...<br> 7437dd7cddfSDavid du Colombier {{ blank line if any declarations above }}<br> 7447dd7cddfSDavid du Colombier ... 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 ... 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 ... 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 ... subordinate code ...<br> 7767dd7cddfSDavid du Colombier<b><tt>} else if (</tt></b> ...<b><tt> ) {</tt></b><br> 7777dd7cddfSDavid du Colombier ... subordinate code ...<br> 7787dd7cddfSDavid du Colombier<b><tt>} else {</tt></b><br> 7797dd7cddfSDavid du Colombier ... 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 ... subordinate code ...<br> 7907dd7cddfSDavid du Colombier<b><tt>} else {</tt></b><br> 7917dd7cddfSDavid du Colombier<b><tt> if (</tt></b> ...<b><tt> ) {</tt></b><br> 7927dd7cddfSDavid du Colombier ... subordinate code ...<br> 7937dd7cddfSDavid du Colombier<b><tt> } else {</tt></b><br> 7947dd7cddfSDavid du Colombier ... subordinate code ...<br> 7957dd7cddfSDavid du Colombier<b><tt> }</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 ... 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>-></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>&&</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 && 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>&</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 << 3) | (y >> 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 (pgls->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 (pgls->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 ... 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 ... members ...<br> 10083ff48bf5SDavid du Colombier <b><tt>xxx_t *</tt></b>ptr_member_name;<br> 10093ff48bf5SDavid du Colombier ... 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># 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 ... 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 T *</tt></b> to type 10373ff48bf5SDavid du Colombier<b><tt>T *</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 T *</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 *</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 gx_device_printer *const pdev = (gx_device_printer *)dev;</tt></b><br> 10977dd7cddfSDavid du Colombier ...<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 ...<br> 1110*593dc095SDavid du Colombier<b><tt> int x;</tt></b><br> 1111*593dc095SDavid du Colombier ...<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><name> 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><filename><b><tt>_INCLUDED</tt></b><br> 12463ff48bf5SDavid du Colombier<b><tt>#define </tt></b><filename><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><filename><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>< 0 12973ff48bf5SDavid du Colombier <td> 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> 13033ff48bf5SDavid du Colombier <td>Normal return 13043ff48bf5SDavid du Colombier<tr valign=top> <td align=right>> 0 13053ff48bf5SDavid du Colombier <td> 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>< 0 13183ff48bf5SDavid du Colombier <td> 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> 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> 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 ... members ...<br> 13443ff48bf5SDavid du Colombier<b><tt>};</tt></b><br> 13453ff48bf5SDavid du Colombier<b><tt>#define private_st_xxx() /* in </tt></b><filename><tt><b>.c */\</tt></b><br> 13463ff48bf5SDavid du Colombier<b><tt> gs_private_st_</tt></b><whatever><b><tt>(st_xxx, xxx_t,\</tt></b><br> 13473ff48bf5SDavid du Colombier<b><tt> "xxx_t", xxx_enum_ptrs, xxx_reloc_ptrs,\</tt></b><br> 13483ff48bf5SDavid du Colombier<b><tt> </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(<filename><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 (*virtu)(P1(xxx_t *))</tt></b>, and we have a variable 14263ff48bf5SDavid du Colombierdeclared as <b><tt>xxx_t *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 xxx_procs *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 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 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 type1 member1;\<br> 14853ff48bf5SDavid du Colombier </tt></b>...<b><tt><br> 14863ff48bf5SDavid du Colombier typeN memberN<br> 14873ff48bf5SDavid du Colombier<br> 14883ff48bf5SDavid du Colombiertypedef struct gx_device_s {<br> 14893ff48bf5SDavid du Colombier gx_device_common;<br> 14903ff48bf5SDavid du Colombier} gx_device;<br> 14913ff48bf5SDavid du Colombier<br> 14923ff48bf5SDavid du Colombier#define private_st_gx_device() /* in gsdevice.c */\<br> 14933ff48bf5SDavid du Colombier gs_private_st_</tt></b><whatever><b><tt>(st_gx_device, gx_device,\<br> 14943ff48bf5SDavid du Colombier "gx_device", device_enum_ptrs, device_reloc_ptrs,\<br> 14953ff48bf5SDavid du Colombier </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 gx_device_common;\<br> 15043ff48bf5SDavid du Colombier gx_device *target<br> 15053ff48bf5SDavid du Colombier<br> 15063ff48bf5SDavid du Colombiertypedef struct gx_device_forward_s {<br> 15073ff48bf5SDavid du Colombier gx_device_forward_common;<br> 15083ff48bf5SDavid du Colombier} gx_device_forward;<br> 15093ff48bf5SDavid du Colombier<br> 15103ff48bf5SDavid du Colombier#define private_st_device_forward() /* in gsdevice.c */\<br> 15113ff48bf5SDavid du Colombier gs_private_st_suffix_add1(st_device_forward, gx_device_forward,\<br> 15123ff48bf5SDavid du Colombier "gx_device_forward", device_forward_enum_ptrs, device_forward_reloc_ptrs,\<br> 15133ff48bf5SDavid du Colombier 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 gx_device_forward_common;<br> 15253ff48bf5SDavid du Colombier};<br> 15263ff48bf5SDavid du Colombier<br> 15273ff48bf5SDavid du Colombier#define private_st_device_null() /* in gsdevice.c */\<br> 15283ff48bf5SDavid du Colombier gs_private_st_suffix_add0_local(st_device_null, gx_device_null,\<br> 15293ff48bf5SDavid du Colombier "gx_device_null", device_null_enum_ptrs, device_null_reloc_ptrs,\<br> 15303ff48bf5SDavid du Colombier 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>< 0 15593ff48bf5SDavid du Colombier <td> 15603ff48bf5SDavid du Colombier <td>Error return 15613ff48bf5SDavid du Colombier<tr valign=top> <td align=right>0 15623ff48bf5SDavid du Colombier <td> 15633ff48bf5SDavid du Colombier <td>Normal return 15643ff48bf5SDavid du Colombier<tr valign=top> <td align=right>> 0 15653ff48bf5SDavid du Colombier <td> 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 © 1996, 1997, 1998 Aladdin Enterprises. 16063ff48bf5SDavid du ColombierCopyright © 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