1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<head> 4<title>Ghostscript PostScript coding guidelines</title> 5<!-- $Id: Ps-style.htm,v 1.37 2005/10/20 19:46:23 ray Exp $ --> 6<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style"> 7</head> 8 9<body> 10<!-- [1.0 begin visible header] ============================================ --> 11 12<!-- [1.1 begin headline] ================================================== --> 13 14<h1>Ghostscript PostScript coding guidelines</h1> 15 16<!-- [1.1 end headline] ==================================================== --> 17 18<!-- [1.2 begin table of contents] ========================================= --> 19 20<h2>Table of contents</h2> 21 22<blockquote><ul> 23<li><a href="#Summary">Summary of the coding guidelines</a> 24<li><a href="#Introduction">Introduction</a> 25<li><a href="#PS_features">Use of PostScript language features</a> 26<ul> 27<li><a href="#Restrictions">Restrictions</a> 28<li><a href="#Protection">Protection</a> 29<li><a href="#Standard_constructions">Standard constructions</a> 30</ul> 31<li><a href="#File_structuring">File structuring</a> 32<li><a href="#Commenting">Commenting</a> 33<li><a href="#Formatting">Formatting</a> 34<ul> 35<li><a href="#Indentation">Indentation</a> 36<li><a href="#Spaces">Spaces</a> 37</ul> 38<li><a href="#Naming">Naming</a> 39<li><a href="#Miscellany">Miscellany</a> 40<ul> 41<li><a href="#Non_standard_operators">Some useful non-standard operators</a> 42<li><a href="#Useful_procedures">Some useful procedures</a> 43<li><a href="#Other">Other</a> 44</ul> 45</ul></blockquote> 46 47<!-- [1.2 end table of contents] =========================================== --> 48 49<!-- [1.3 begin hint] ====================================================== --> 50 51<p> 52For other information, see the <a href="Readme.htm">Ghostscript 53overview</a>. 54 55<!-- [1.3 end hint] ======================================================== --> 56 57<hr> 58 59<!-- [1.0 end visible header] ============================================== --> 60 61<!-- [2.0 begin contents] ================================================== --> 62 63<h2><a name="Summary"></a>Summary of the coding guidelines</h2> 64 65<ul> 66 67<li>Don't store into literals. 68 69<li>Use <b><tt>loop</tt></b> to create a block with multiple exits. 70 71<li>Use a dictionary or an array for multi-way switches. 72 73<li>Start every file with a copyright notice, the file name, and a one-line 74summary. 75 76<li>Comment every procedure with the arguments and result, and with the 77function of the procedure unless it's obvious. 78 79<li>Comment the stack contents ad lib, and particularly at the beginning of 80every loop body. 81 82<li>Indent every 2 spaces. 83 84<li>Always put { at the end of a line, and } at the beginning of a line, 85unless the contents are very short. 86 87<li>Always put spaces between adjacent tokens. 88 89<li>Use only lower-case letters and digits for names, or Vienna style names, 90except for an initial "." for names only used within a single file. 91 92<li>Don't allocate objects in heavily used code. 93 94<li>Consider factoring out code into a procedure if it is used more than 95once. 96 97</ul> 98 99<hr> 100 101<h2><a name="Introduction"></a>Introduction</h2> 102 103<p> 104The many rules that Ghostscript's code follows almost everywhere are meant 105to produce code that is easy to read. It's important to observe them as 106much as possible in order to maintain a consistent style, but if you find a 107rule getting in your way or producing ugly-looking results once in a while, 108it's OK to break it. 109 110<hr> 111 112<h2><a name="PS_features"></a>Use of PostScript language features</h2> 113 114<h3><a name="Restrictions"></a>Restrictions</h3> 115 116<p> 117If you need to store a value temporarily, don't write into a literal in the 118code, as in this fragment to show a character given the character code: 119 120<blockquote><pre> 121( ) dup 0 4 -1 roll put show 122</pre></blockquote> 123 124<p> 125Instead, allocate storage for it: 126 127<blockquote><pre> 1281 string dup 0 4 -1 roll put show 129</pre></blockquote> 130 131<h3><a name="Protection"></a>Protection</h3> 132 133<p> 134If an object is never supposed to change, use <b><tt>readonly</tt></b> to 135make it read-only. This applies especially to permanently allocated objects 136such as constant strings or dictionaries. 137 138<p> 139During initialization, and occasionally afterwards, it may be necessary to 140store into a read-only dictionary, or to store a pointer to a dictionary in 141local VM into a dictionary in global VM. The operators 142<b><tt>.forceput</tt></b> and <b><tt>.forceundef</tt></b> are available for 143this purpose. To make these operators inaccessible to ordinary programs, 144they are removed from <b><tt>systemdict</tt></b> at the end of 145initialization: system code that uses them should always use 146<b><tt>bind</tt></b> and <b><tt>odef</tt></b> (or 147<b><tt>executeonly</tt></b>) to make uses of them inaccessible as well. 148 149<h3><a name="Standard_constructions"></a>Standard constructions</h3> 150 151<h4>Multi-way conditionals</h4> 152 153<p> 154If you write a block of code with more than about 3 exit points, the usual 155way to do it would be like this: 156 157<blockquote><pre> 158{ 159 ... { 160 ...1 161 } { 162 ... { 163 ...2 164 } { 165 ... { 166 ...3 167 } { 168 ...4 169 } ifelse 170 } ifelse 171 } ifelse 172} 173</pre></blockquote> 174 175<p> 176However, this causes the 4 logically somewhat parallel code blocks to be 177indented differently, and as the indentation increases, it becomes harder to 178see the structure visually. As an alternative, you can do it this way: 179 180<blockquote><pre> 181{ % The loop doesn't actually loop: it just provides a common exit. 182 ... { 183 ...1 184 exit 185 } if 186 ... { 187 ...2 188 exit 189 } if 190 ... { 191 ...3 192 exit 193 } if 194 ...4 195 exit 196} loop 197</pre></blockquote> 198 199<p> 200Don't forget the final exit, to prevent the loop from actually looping. 201 202<h4>Switches</h4> 203 204<p> 205Use a dictionary or an array of procedures to implement a 'switch', rather 206than a series of conditionals, if there are more than about 3 cases. For 207example, rather than: 208 209<blockquote><pre> 210dup /a eq { 211 pop ...a 212} { 213 dup /b eq { 214 pop ...b 215 } { 216 dup /c eq { 217 pop ...c 218 } { 219 ...x 220 } ifelse 221 } ifelse 222} ifelse 223</pre></blockquote> 224 225<p> 226(or using the loop/exit construct suggested above), consider: 227 228<blockquote><pre> 229/xyzdict mark 230 /a {...a} bind 231 /b {...b} bind 232 /c {...c} bind 233.dicttomark readonly def 234... 235//xyzdict 1 index .knownget { 236 exch pop exec 237} { 238 ...x 239} ifelse 240</pre></blockquote> 241 242<hr> 243 244<h2><a name="File_structuring"></a>File structuring</h2> 245 246<p> 247Every code file should start with comments containing 248 249<ol> 250<li>a copyright notice; 251<li>the name of the file in the form of an RCS Id: 252 253<blockquote><pre> 254% Id$: filename.ps $ 255</pre></blockquote> 256 257<li>a very brief summary (preferably only one line) of what the file 258contains. 259</ol> 260 261<p> 262If you create a file by copying the beginning of another file, be sure to 263update the copyright year and change the file name. 264 265<hr> 266 267<h2><a name="Commenting"></a>Commenting</h2> 268 269<p> 270If a file has well-defined functional sections, put a comment at the 271beginning of each section to describe its purpose or function. 272 273<p> 274Put a comment before every procedure to describe what the procedure does, 275unless it's obvious or the procedure's function is defined by the PLRM. In 276case of doubt, don't assume it's obvious. If the procedure may execute a 277deliberate 'stop' or 'exit' not enclosed in 'stopped' or a loop 278respectively, that should be mentioned. However, information about the 279arguments and results should go in the argument and result comment 280(described just below) if possible, not the functional comment. 281 282<p> 283Put a comment on every procedure to describe the arguments and results: 284 285<blockquote><pre> 286/hypot { % <num1> <num2> hypot <real> 287 dup mul exch dup mul add sqrt 288} def 289</pre></blockquote> 290 291<p> 292There is another commenting style that some people prefer to the above: 293 294<blockquote><pre> 295/hypot { % num1 num2 --> realnum 296 dup mul exch dup mul add sqrt 297} def 298</pre></blockquote> 299 300<p> 301We have adopted the first style for consistency with Adobe's documentation, 302but we recognize that there are technical arguments for and against both 303styles, and might consider switching some time in the future. If you have 304strong feelings either way, please make your opinion known to 305<b><tt>gs-devel@ghostscript.com</tt></b>. 306 307<p> 308Put comments describing the stack contents wherever you think they will be 309helpful; put such a comment at the beginning of every loop body unless you 310have a good reason not to. 311 312<p> 313When you change a piece of code, do <em>not</em> include a comment with your 314name or initials. Also, do <em>not</em> retain the old code in a comment, 315unless you consider it essential to explain something about the new code; in 316that case, retain as little as possible. (CVS logs do both of these things 317better than manual editing.) However, if you make major changes in a 318procedure or a file, you may put your initials, the date, and a brief 319comment at the head of the procedure or file respectively. 320 321<hr> 322 323<h2><a name="Formatting"></a>Formatting</h2> 324 325<h3><a name="Indentation"></a>Indentation</h3> 326 327<p> 328Indent 2 spaces per indentation level. You may use tabs at the left margin 329for indentation, with 1 tab = 8 spaces, but you should not use tabs anywhere 330else, except to place comments. 331 332<p> 333Indent { } constructs like this: 334 335<blockquote><pre> 336... { 337 ... 338} { 339 ... 340} ... 341</pre></blockquote> 342 343<p> 344If the body of a conditional or loop is no more than about 20 characters, 345you can put the entire construct on a single line if you want: 346 347<blockquote><pre> 348... { ... } if 349</pre></blockquote> 350 351rather than 352 353<blockquote><pre> 354... { 355 ... 356} if 357</pre></blockquote> 358 359<p> 360There is another indentation style that many people prefer to the above: 361 362<blockquote><pre> 363... 364{ ... 365} 366{ ... 367} ... 368</pre></blockquote> 369 370<p> 371We have adopted the first style for consistency with our C code, but we 372recognize that there are technical arguments for and against both styles, 373and might consider switching some time in the future. If you have strong 374feelings either way, please make your opinion known to 375<b><tt>gs-devel@ghostscript.com</tt></b>. 376 377<h3><a name="Spaces"></a>Spaces</h3> 378 379<p> 380Always put spaces between two adjacent tokens, even if this isn't strictly 381required. E.g., 382 383<blockquote><pre> 384/Halftone /Category findresource 385</pre></blockquote> 386 387<p> 388not 389 390<blockquote><pre> 391/Halftone/Category findresource 392</pre></blockquote> 393 394<hr> 395 396<h2><a name="Naming"></a>Naming</h2> 397 398<p> 399All names should consist only of letters and digits, possibly with an 400initial ".", except for names drawn from the PostScript or PDF reference 401manual, which must be capitalized as in the manual. In general, an initial 402"." should be used for those and only those names that are not defined in a 403private dictionary but that are meant to be used only in the file where they 404are defined. 405 406<p> 407For edits to existing code, names made up of multiple words should not use 408any punctuation, or capitalization, to separate the words, again except for 409names that must match a specification. For new code, you may use this 410convention, or you may use the "Vienna" convention of capitalizing the first 411letter of words, e.g., <b><tt>readSubrs</tt></b> rather than 412<b><tt>readsubrs</tt></b>. If you use the Vienna convention, function names 413should start with an upper case letter, variable names with a lower case 414letter. Using the first letter of a variable name to indicate the 415variable's type is optional, but if you do it, you should follow existing 416codified usage (****** WE NEED A REFERENCE FOR THIS ******). 417 418<hr> 419 420<h2><a name="Miscellany"></a>Miscellany</h2> 421 422<h3><a name="Non_standard_operators"></a>Some useful non-standard 423operators</h3> 424 425<dl> 426 427<dt><b><tt><obj1> <obj2> ... <objn> <n> .execn ...</tt></b> 428<dd>This executes <b><tt>obj1</tt></b> through <b><tt>objn</tt></b> in that 429order, essentially equivalent to 430 431<blockquote><pre> 432<obj1> <obj2> ... <objn> <n> array astore {exec} forall 433</pre></blockquote> 434 435<p> 436except that it doesn't actually create the array. 437 438<dt><b><tt><dict> <key> <b>.knownget</b> <value> true</tt></b> 439<dt><b><tt><dict> <key> <b>.knownget</b> false</tt></b> 440 441<dd>This combines <b><tt>known</tt></b> and <b><tt>get</tt></b> in the 442obvious way. 443 444<dt><b><tt><name> <proc> odef -</tt></b> 445 446<dd>This defines <b><tt>name</tt></b> as a "pseudo-operator". The value of 447<b><tt>name</tt></b> will be executable, will have type 448<b><tt>operatortype</tt></b>, and will be executed if it appears directly in 449the body of a procedure (like an operator, unlike a procedure), but what 450will actually be executed will be <b><tt>proc</tt></b>. In addition, if the 451execution of <b><tt>proc</tt></b> is ended prematurely (by 452<b><tt>stop</tt></b>, including the <b><tt>stop</tt></b> that is normally 453executed when an error occurs, or <b><tt>exit</tt></b>) and the operand and 454dictionary stacks are at least as deep as they were when the "operator" was 455invoked, the stacks will be cut back to their original depths before the 456error is processed. Thus, if pseudo-operator procedures are careful not to 457remove any of their operands until they reach a point in execution beyond 458which they cannot possibly cause an error, they will behave just like 459operators in that the stacks will appear to be unchanged if an error occurs. 460 461</dl> 462 463<h3><a name="Useful_procedures"></a>Some useful procedures</h3> 464 465<dl> 466 467<dt><b><tt><object> <errorname> signalerror -</tt></b> 468 469<dd>Signal an error with the given name and the given "current object". 470This does exactly what the interpreter does when an error occurs. 471 472</dl> 473 474<h3><a name="Other"></a>Other</h3> 475 476<p> 477If you can avoid it, don't allocate objects (strings, arrays, dictionaries, 478gstates, etc.) in commonly used operators or procedures: these will need to 479be garbage collected later, slowing down execution. Instead, keep values on 480the stack, if you can. The <b><tt>.execn</tt></b> operator discussed above 481may be helpful in doing this. 482 483<p> 484If you find yourself writing the same stretch of code (more than about half 485a dozen tokens) more than once, ask yourself whether it performs a function 486that could be made into a procedure. 487 488 489<!-- [2.0 end contents] ==================================================== --> 490 491<!-- [3.0 begin visible trailer] =========================================== --> 492<hr> 493 494<p> 495<small>Copyright © 2000 Aladdin Enterprises. All rights 496reserved.</small> 497 498<p> 499<small>This file is part of AFPL Ghostscript. See the <a 500href="Public.htm">Aladdin Free Public License</a> (the "License") for full 501details of the terms of using, copying, modifying, and redistributing AFPL 502Ghostscript.</small> 503 504<p> 505<small>Ghostscript version 8.53, 20 October 2005 506 507<!-- [3.0 end visible trailer] ============================================= --> 508 509</body> 510</html> 511