/usr/share/doc/ghostscript/C-style.htm is in ghostscript-doc 9.06~dfsg-2+deb8u7.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=us-ascii">
<title>Ghostscript C coding guidelines</title>
<!-- Originally: c-style.txt -->
<link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style">
</head>
<body>
<!-- [1.0 begin visible header] ============================================ -->
<!-- [1.1 begin headline] ================================================== -->
<h1>Ghostscript C coding guidelines</h1>
<!-- [1.1 end headline] ==================================================== -->
<!-- [1.2 begin table of contents] ========================================= -->
<h2>Table of contents</h2>
<blockquote><ul>
<li><a href="#Introduction">Introduction</a>
<li><a href="#C_language">C language do's and don'ts</a>
<ul>
<li>Preprocessor:
<a href="#Conditionals">Conditionals</a>,
<a href="#Macros">Macros</a>,
<a href="#Preprocessor_other">Other</a>
<li><a href="#Lexical_elements">Lexical elements</a>
<li><a href="#Scoping">Scoping</a>
<li>Data types:
<a href="#Scalars">Scalars</a>,
<a href="#Arrays">Arrays</a>,
<a href="#Typedefs">Typedefs</a>,
<a href="#Structures">Structures</a>,
<a href="#Unions">Unions</a>
<li><a href="#Expressions">Expressions</a>
<li><a href="#Statements">Statements</a>
<li><a href="#Procedures">Procedures</a> (prototypes and definitions)
<li><a href="#Standard_library">Standard library</a>
</ul>
<li><a href="#Language_extensions">Language extensions</a>
<li><a href="#Stylistic_conventions">Stylistic conventions</a>
<ul>
<li>Formatting:
<a href="#Indentation">Indentation</a>,
<a href="#Spaces">Spaces</a>,
<a href="#Parentheses">Parentheses</a>
<li><a href="#Preprocessor_style">Preprocessor</a>
<li><a href="#Naming">Naming</a>
<li><a href="#Types">Types</a>
<li><a href="#Procedures_style">Procedures</a>,
<li>Miscellany:
<a href="#Local_variables">Local variables</a>,
<a href="#Compiler_warnings">Compiler warnings</a>
</ul>
<li><a href="#File_structuring">File structuring and naming</a>
<ul>
<li><a href="#All_files">All files</a>
<li><a href="#Makefiles">Makefiles</a>
<li><a href="#General_C_code">General C Code</a>
<li><a href="#Headers">Headers (<code>.h</code> files)</a>
<li><a href="#Source">Source (<code>.c</code> files)</a>
</ul>
<li><a href="#Conventions">Ghostscript conventions</a>
<ul>
<li><a href="#Specific_names">Specific names</a>:
<a href="#code"><code>code</code></a>,
<a href="#status"><code>status</code></a>
<li><a href="#Structure_type_descriptors">Structure type descriptors</a>
<li><a href="#Objects">"Objects"</a>
<li><a href="#Error_handling">Error handling</a>
</ul>
</ul></blockquote>
<!-- [1.2 end table of contents] =========================================== -->
<!-- [1.3 begin hint] ====================================================== -->
<p>
For other information, see the <a href="Readme.htm">Ghostscript
overview</a>.
<!-- [1.3 end hint] ======================================================== -->
<hr>
<!-- [1.0 end visible header] ============================================== -->
<!-- [2.0 begin contents] ================================================== -->
<h2><a name="Introduction"></a>Introduction</h2>
<p>
This document describes Ghostscript's C coding conventions. It is primarily
<em>prescriptive</em>, documenting what developers should do when writing
new code; the companion developer documentation (<a
href="Develop.htm">Develop.htm</a>) is primarily <em>descriptive</em>,
documenting the way things are.
<p>
We encourage following the general language usage and stylistic rules for
any code that will be integrated with Ghostscript, even if the code doesn't
use Ghostscript's run-time facilities or have anything to do with
PostScript, PDF, or page description languages. Ghostscript itself follows
some additional conventions; these are documented separately under "<a
href="#Conventions">Ghostscript conventions</a>" below.
<hr>
<h2><a name="C_language"></a>C language do's and don'ts</h2>
<p>
There are several different versions of the C language, and even of the ANSI
C standard. Ghostscript versions through 7.0 were designed to compile on
pre-ANSI compilers as well as on many compilers that implemented the ANSI
standard with varying faithfulness. Ghostscript versions since 7.0 do not
cater for pre-ANSI compilers: they must conform to the ANSI 1989 standard
(ANS X3.159-1989), with certain restrictions and a few conventional
additions.
<h3>Preprocessor</h3>
<h4><a name="Conditionals"></a>Conditionals</h4>
Restrictions:
<ul>
<li>Don't assume that <code>#if</code> will treat undefined names as 0.
While the ANSI standard requires this, it may produce a warning.
<li>In <code>.c</code> files, don't use preprocessor conditionals that
test for individual platforms or compilers. Use them only in header files
named xxx<code>_.h</code>.
</ul>
<h4><a name="Macros"></a>Macros</h4>
<p>
Restrictions:
<ul>
<li>Don't redefine a macro, even with the same definition, without using
<code>#undef</code>.
<li><code>CAPITALIZE</code> macro names unless there is a good reason not
to.
<li>Even though the legacy code contains some macros which contain
control flow statments, avoid the use of this in new code and do not
create macros which contain hidden control flow, especially 'return'.
The use of control flow in macros complicates debug significantly
requiring tedious expansion of macros to build a module to be debugged
or resorting to disassembly windows to set breakpoints or to trace
flow.
<li>Don't use a macro call within a macro argument if the call expands to a
token sequence that includes any commas not within parentheses: this
produces different results depending on whether the compiler expands the
inner call before or after the argument is substituted into the macro body.
(The ANSI standard says that calls must be expanded after substitution, but
some compilers do it the other way.)
<li>Don't use macro names, even inadvertently, in string constants. Some
compilers erroneously try to expand them.
<li>Don't use macros to define shorthands for casted pointers. For
instance, avoid
<blockquote><code>
#define fdev ((gx_device_fubar *)dev)
</code></blockquote>
<p>
and instead use
<blockquote><code>
gx_device_fubar * const fdev = (gx_device_fubar *)dev;
</code></blockquote>
<p>
The use of <code>const</code> alerts the reader that this is effectively
a synonym.
<li>If a macro generates anything larger than a single expression (that is,
one or more statements), surround it with <code>BEGIN</code> and
<code>END</code>. These work around the fact that simple statements and
compound statements in C can't be substituted for each other syntactically.
<li>If a macro introduces local variables, only use names that end with an
underscore (<code>_</code>), such as <code>code_</code>. This avoids
clashes both with ordinary variable names (which should never end with an
underscore) and with system-defined names (which may begin with an
underscore).
</ul>
<h3><a name="Preprocessor_other"></a>Other</h3>
<p>
Restrictions:
<ul>
<li>Only use <code>#pragma</code> in files that are explicitly identified
as being platform-dependent. Many compilers complain if this is used at
all, and some complain if they don't recognize the specific pragma being
requested (both incorrect according to the ANSI standard).
</ul>
<h3><a name="Lexical_elements"></a>Lexical elements</h3>
<p>
Do not use:
<ul>
<li>ANSI trigraphs (??x)
<li>Nested comments (/* /* */ */) (not ANSI compliant, but often accepted)
<li>Multi-character character constants ('abc')
<li>Wide-character character or string constants (L'x', L"x")
</ul>
<p>
Restrictions:
<ul>
<li>Procedure and static variable names must be 31 characters or less.
<li>Externally visible procedure and variable names must be unique in the
first 23 characters.
</ul>
<h3><a name="Scoping"></a>Scoping (extern, static, ...)</h3>
<p>
Do not use:
<ul>
<li><code>register</code>
</ul>
<p>
Restrictions:
<ul>
<li>Do not allow a global variable (constant) to have more than one
non-<code>extern</code> definition, even though some ANSI C compilers
allow this. Every global constant should have exactly one definition, in a
<code>.c</code> file, and preferably just one <code>extern</code>
declaration, in a header file.
<li><code>static</code> or variables must be
<code>const</code> and initialized: non-<code>const</code> statically
allocated variables are incompatible with reentrancy, and we're in the
process of eliminating all of them.
<li>Do not use <code>extern</code> in <code>.c</code> files, only in
<code>.h</code> files, unless you have a very good reason for it (e.g.,
as in <a href="../psi/iconf.c">iconf.c</a>). There are too many such
<code>extern</code>s in the code now: we are eliminating them over time.
<li>Do not declare the same name as both <code>static</code>
and non-<code>static</code> within the same
compilation. (Some compilers complain, some do not.) This is especially a
problem for procedures: it is easy to declare a procedure as
<code>static</code> near the beginning of a file and accidentally not
declare it <code>static</code> where it is defined later in the file.
<li>Even though the ANSI standard allows initialized external declarations
(<code>extern int x = 0</code>), don't use them.
</ul>
<h3><a name="Scalars"></a>Scalars</h3>
<p>
Restrictions:
<ul>
<li>Avoid using <code>char</code>, except for <code>char *</code>
for a pointer to a string. Don't assume that <code>char</code> is
signed; also don't assume it is unsigned.
<li>Never cast a <code>float</code> to a <code>double</code>
explicitly. ANSI compilers in their default mode do all floating point
computations in double precision, and handle such casts automatically.
<li>Don't use <code>long long</code>: even though it is in the ANSI
standard, not all compilers support it. Use the
<code>(u)int64_t</code> types from <code>stdint_.h</code> instead.
<li>Don't assume anything about whether <code>sizeof(long)</code> is less
than, equal to, or greater than <code>sizeof(ptr)</code>. (However, you
can make such comparisons in preprocessor conditionals using
<code>ARCH_SIZEOF_LONG</code> and <code>ARCH_SIZEOF_PTR</code>.)
</ul>
<h3><a name="Arrays"></a>Arrays</h3>
<p>
Restrictions:
<ul>
<li>Don't declare arrays of size 0. (The newer ANSI standard allows this,
but the older one doesn't.)
<li>Don't declare an array of size 1 at the end of a structure to indicate
that a variable-size array follows.
<li>Don't declare initialized <code>auto</code> arrays.
</ul>
<h3><a name="Typedefs"></a>Typedefs</h3>
<p>
Restrictions:
<ul>
<li>Don't use <code>typedef</code> for function types, such as
<blockquote>
<code>typedef int proc_xyz_t(double, int *);</code>
</blockquote>
<p>Many compilers don't handle this correctly -- they will give errors, or
do the wrong thing, when declaring variables of type
<code>proc_xyz_t</code> and/or <code>proc_xyz_t *</code>. Instead, do
this:
<blockquote>
<code>#define PROC_XYZ(proc) int proc(double, int *)<br>
PROC_XYZ(some_proc); /* declare a procedure of this type */<br>
typedef PROC_XYZ((*proc_xyz_ptr_t)); /* define a type for procedure ptrs */<br>
<br>
proc_xyz_ptr_t pp; /* pointer to procedure */</code>
</blockquote>
<li>Don't redefine <code>typedef</code>'ed names, even with the same
definition. Some compilers complain about this, and the standard doesn't
allow it.
</ul>
<h3><a name="Structures"></a>Structures</h3>
<p>
Restrictions:
<ul>
<li>Don't use anonymous structures if you can possibly avoid it, except
occasionally as components of other structures. Ideally, use the
<code>struct</code> keyword only for declaring named structure types,
like this:
<blockquote>
<code>typedef struct xxx_s {</code><br>
... members ...<br>
<code>} xxx_t;</code>
</blockquote>
<li>Use <code>struct</code> only when declaring structure types, never
for referring to them (e.g., never declare a variable as type
<code>struct xxx_s *</code>).
<li>Don't assume that the compiler will (or won't) insert padding in
structures to align members for best performance. To preserve alignment,
only declare structure members that are narrower than an <code>int</code>
if there will be a lot of instances of that structure in memory. For such
structures, insert <code>byte</code> and/or <code>short</code> padding
members as necessary to re-establish <code>int</code> alignment.
<li>Don't declare initialized <code>auto</code> structures.
</ul>
<h3><a name="Unions"></a>Unions</h3>
<p>
Restrictions:
<ul>
<li>Use unions only as components of structures, not as typedefs in their
own right.
<li>Don't attempt to initialize unions: not all compilers support this, even
though it is in the 1989 ANSI standard.
</ul>
<h3><a name="Expressions"></a>Expressions</h3>
<p>
Restrictions:
<ul>
<li>Don't assign a larger integer data type to a smaller one without a cast
(<code>int_x = long_y</code>).
<li>It's OK to use the address of a structure or array element
(<code>&p->e</code>, <code>&a[i]</code>) locally, or pass it to a
procedure that won't store it, but don't store such an address in allocated
storage unless you're very sure of what you're doing.
<li>Don't use conditional expressions with structure or union values.
(Pointers to structures or unions are OK.)
<li>For calling a variable or parameter procedure, use
<code>ptr->func(...)</code>. Some old code uses explicit indirection,
<code>(*ptr->func)(...)</code>: don't use this in new code.
<li>Don't write expressions that depend on order of evaluation, unless the
order is created explicitly by use of <code>||</code>,
<code>&&</code>, <code>?:</code>, <code>,</code>, or
function nesting (the arguments of a function must be evaluated before the
function is called). In particular, don't assume that the arguments of a
function will be evaluated left-to-right, or that the left side of an
assignment will be evaluated before the right.
<li>Don't mix integer and enumerated types ad lib: treat enumerated types as
distinct from integer types, and use casts to convert between the two.
(Some compilers generate warnings if you do not do this.)
</ul>
<h3><a name="Statements"></a>Statements</h3>
<p>
Restrictions:
<ul>
<li>If you use an expression as a statement, other than an assignment or a
function call with <code>void</code> return value, enclose it explicitly
in <code>DISCARD()</code>.
<li>The type of the operand of a <code>switch</code> must match the type
of the case labels, whether the labels are <code>int</code>s or the
members of an <code>enum</code> type. (Use a cast if necessary.)
<li>It is OK for one case of a switch to "fall through" into another (i.e.,
for the statement just before a case label not to be a control transfer),
but a comment <code>/* falls through */</code> is
required.
<li>If you are returning an error code specified explicitly (e.g.,
<code>return gs_error_rangecheck</code> or
<code>return e_rangecheck</code>), use
<code>return_error()</code> rather than plain <code>return</code>.
However, if the program is simply propagating an error code generated
elsewhere, as opposed to generating the error, use <code>return</code>
(e.g., <code>if (code < 0) return code</code>).
</ul>
<h3><a name="Procedures"></a>Procedures</h3>
<p>
Restrictions:
<ul>
<li>Provide a prototype for every procedure, and make sure the prototype is
available at every call site. If the procedure is local to a file
(<code>static</code>), the prototype should precede the procedure, in
the same file; if the procedure is global, the prototype should be in a
header file.
<li>If a procedure parameter is itself a procedure, do list its parameter
types rather than just using <code>()</code>. For example,
<blockquote><code>
int foo(int (*callback)(int, int));
</code></blockquote>
<p>
rather than just
<blockquote><code>
int foo(int (*callback)());
</code></blockquote>
<li>Don't use the <code>P</code>* macros in new code. (See the
Procedures section of <a href="#Language_extensions">Language extensions</a>
below for more information.)
<li>Always provide an explicit return type for procedures, in both the
prototype and the definition: don't rely on the implicit declaration as
<code>int</code>.
<li>Don't use <code>float</code> as the return type of a procedure,
unless there's a special reason. Floating point hardware typically does
everything in double precision internally and has to do extra work to
convert between double and single precision.
<li>Don't declare parameters as being of type <code>float</code>,
<code>short</code>, or <code>char</code>. If you do this and forget
to include the prototype at a call site, ANSI compilers will generate
incompatible calling sequences. Use <code>floatp</code> (a synonym for
<code>double</code>, mnemonic for "float parameter") instead of
<code>float</code>, and use <code>int</code> or <code>uint</code>
instead of <code>short</code> or <code>char</code>.
</ul>
<h3><a name="Standard_library"></a>Standard library</h3>
<p>
Restrictions:
<ul>
<li>Only use library features that are documented in the established ANSI
standard (e.g., Harbison & Steele's book). Do not use procedures that are
"standards" promulgated by Microsoft (e.g., <code>stricmp</code>), or
originate in BSD Unix (e.g., <code>strcasecmp</code>), or were added in
later versions of the standard such as C 9X.
<li>Do not use any features from <code>stdio.h</code> that assume the
existence of <code>stdin</code>, <code>stdout</code>, or
<code>stderr</code>. See <a href="../base/gsio.h">gsio.h</a> for the full
list. Instead, use <code>gs_stdin</code> et al.
</ul>
<hr>
<h2><a name="Language_extensions"></a>Language extensions</h2>
<h3>Scoping</h3>
<dl>
<dt><code>static</code>
<dd>Ghostscript assumes the compiler supports the <code>static</code>
keyword for declaring variables and procedures as local to a particular
source file.
<dt><code>inline</code>
<dd><code>inline</code> is available even if the compiler does not
support it. Be aware, however, that it may have no effect. In particular,
do not use <code>inline</code> in header files. Instead, use the
<code>extern_inline</code> facility described just below.
<dt><code>extern_inline</code>
<dd>Compilers that do support <code>inline</code> vary in how they decide
whether to (also) compile a closed-code copy of the procedure. Because of
this, putting an <code>inline</code> procedure in a header file may
produce multiple closed copies, causing duplicate name errors at link time.
<code>extern_inline</code> provides a safe way to put
<code>inline</code> procedures in header files, regardless of compiler.
Unfortunately, the only way we've found to make this fully portable involves
a fair amount of boilerplate. For details, please see <a
href="../base/stdpre.h">stdpre.h</a>.
</dl>
<h3>Scalar types</h3>
<dl>
<dt><code>bool, true, false</code>
<dd><code>bool</code> is intended as a Boolean type, with canonical
values <code>true</code> and <code>false</code>. In a more reasonable
language, such as Java, <code>bool</code> is an enumerated type requiring
an explicit cast to or from <code>int</code>; however, because C's
conditionals are defined as producing <code>int</code> values, we can't
even define <code>bool</code> as a C <code>enum</code> without
provoking compiler warnings.
<p>
Even though <code>bool</code> is a synonym for <code>int</code>, treat
them as conceptually different types:
<ul>
<li>Initialize or set <code>bool</code> variables to <code>true</code>
or <code>false</code>, not 0 or 1.
<li>Use the Boolean operators <code>!</code>, <code>&&</code>,
and <code>||</code> only with Booleans. Don't use the idiom
<code>!!x</code> to create a Boolean that is true iff <code>x</code>
!= 0: use <code>x != 0</code>.
<li>Use an explicit <code>(int)</code> cast to convert a Boolean to an
integer.
</ul>
<dt><code>byte, ushort, uint, ulong</code>
<dd>These types are simply shorthands for <code>unsigned char, short, int,
long</code>.
<p>
In addition, the use of <code>byte *</code> indicates a
Ghostscript-style string, with explicit length given separately, as
opposed to a null terminated C-style string, which is <code>char
*</code>.
<dt><code>floatp</code>
<dd>This is a synonym for <code>double</code>. It should be used for,
and only for, procedure parameters that would otherwise be
<code>float</code>. (As noted above, procedure parameters should not be
declared as <code>float</code>.)
<dt><code>bits8, bits16, bits32</code>
<dd>These are unsigned integer types of the given width. Use them wherever
the actual width matters: do <em>not</em>, for example, use
<code>short</code> assuming that it is 16 bits wide. New code can use
the C99 fixed-width types from <code>stdint_.h</code>.
</dl>
<hr>
<h2><a name="Stylistic_conventions"></a>Stylistic conventions</h2>
<p>
Ghostscript's coding rules cover not only the use of the language, but also
many stylistic issues like the choice of names and the use of whitespace.
The stylistic rules are meant to produce code that is easy to read. It's
important to observe them as much as possible in order to maintain a
consistent style, but if you find these rules getting in your way or
producing ugly-looking results once in a while, it's OK to break it.
<h3><a name="Formatting"></a>Formatting</h3>
<h4><a name="Indentation"></a>Indentation</h4>
<p>
We've formatted all of our code using the GNU <code>indent</code> program.
<blockquote><code>
indent -bad -nbap -nsob -br -ce -cli4 -npcs -ncs \<br>
-i4 -di0 -psl -lp -lps somefile.c
</code></blockquote>
<p>
does a 98% accurate job of producing our preferred style. Unfortunately,
there are bugs in all versions of GNU <code>indent</code>, requiring
both pre- and post-processing of the code.
<p>
Put indentation points every 4 spaces, with 8 spaces = 1 tab stop.
<p>
Don't indent the initial <code>#</code> of preprocessor commands.
However, for nested preprocessor commands, do use indentation between the
<code>#</code> and the command itself. Use 2 spaces per level of
nesting, e.g.:
<blockquote>
<code>#ifndef xyz</code><br>
<code># define xyz 0</code><br>
<code>#endif</code>
</blockquote>
<p>
For assignments (including chain assignments), put the entire statement on
one line if it will fit; if not, break it after a <code>=</code> and
indent all the following lines. I.e., format like this:
<blockquote>
var1 <code>=</code> value<code>;</code><br>
var1 <code>=</code> var2 <code>=</code> value<code>;</code><br>
var1 <code>=</code><br>
value<code>;</code><br>
var1 <code>=</code><br>
var2 <code>=</code> value<code>;</code><br>
var1 <code>=</code> var2 <code>=</code><br>
value<code>;</code>
</blockquote>
<p>
But not like this:
<blockquote>
var1 <code>=</code><br>
var2 <code>=</code> value<code>;</code>
</blockquote>
<p>
Indent in-line blocks thus:
<blockquote>
<code>{</code><br>
... declarations ...<br>
{{ blank line if any declarations above }}<br>
... statements ...<br>
<code>}</code>
</blockquote>
<p>
Similarly, indent procedures thus:
<blockquote>
return_type<br>
proc_name(... arguments ...)<br>
<code>{</code><br>
... declarations ...<br>
{{ blank line if any declarations above }}<br>
... statements ...<br>
<code>}</code>
</blockquote>
<p>
If a control construct (<code>if</code>, <code>do</code>,
<code>while</code>, or <code>for</code>) has a one-line body, use
this:
<blockquote>
... control construct ...<br>
... subordinate simple statement ...
</blockquote>
This is considered particularly important so that a breakpoint can be
set inside the conditional easily.
<p>
If it has a multi-line body, use this:
<blockquote>
... control construct ... <code>{</code><br>
... subordinate code ...<br>
<code>}</code>
</blockquote>
<p>
If the subordinate code has declarations, see blocks above.
<p>
For if-else statements, do this:
<blockquote>
<code>if (</code> ...<code> ) {</code><br>
... subordinate code ...<br>
<code>} else if (</code> ...<code> ) {</code><br>
... subordinate code ...<br>
<code>} else {</code><br>
... subordinate code ...<br>
<code>}</code>
</blockquote>
<p>
When there are more than two alternatives, as in the example above, use the
above ("parallel") syntax rather than the following ("nested") syntax:
<blockquote>
<code>if (</code> ...<code> ) {</code><br>
... subordinate code ...<br>
<code>} else {</code><br>
<code> if (</code> ...<code> ) {</code><br>
... subordinate code ...<br>
<code> } else {</code><br>
... subordinate code ...<br>
<code> }</code><br>
<code>}</code>
</blockquote>
<p>
Similarly, for do-while statements, do this:
<blockquote>
<code>do {</code><br>
... body ...<br>
<code>} while (</code> ... condition ... <code>);</code>
</blockquote>
<h4><a name="Spaces"></a>Spaces</h4>
<p>
Do put a space:
<ul>
<li>after every comma and semicolon, unless it ends a line;
<li>around every binary operator other than "<code>-></code>" and
"<code>.</code>", although you can omit the spaces around the innermost
operator in a nested expression if you like;
<li>on both sides of the parentheses of an <code>if</code>, <code>for</code>, or <code>while</code>.
</ul>
<p>
Don't put a space:
<ul>
<li>at the end of a line;
<li>before a comma or semicolon;
<li>after unary prefix operators;
<li>before the parenthesis of a macro or procedure call.
</ul>
<h4><a name="Parentheses"></a>Parentheses</h4>
<p>
Parentheses are important in only a few places:
<ul>
<li>Around the inner subexpressions in expressions that mix
<code>&&</code> and <code>||</code>, even if they are not
required by precedence, for example
<blockquote><code>
(xx && yy) || zz
</code></blockquote>
<li>Similarly around inner subexpressions in expressions that mix
<code>&</code>, <code>|</code>, or shifts, especially if mixing
these with other operators, for instance
<blockquote><code>
(x << 3) | (y >> 5)
</code></blockquote>
<li>In macro definitions around every use of an argument that logically
could be an expression, for example
<blockquote><code>
((x) * (x) + (y) * (y))
</code></blockquote>
</ul>
<p>
Anywhere else, given the choice, use fewer parentheses.
<p>
For stylistic consistency with the existing Ghostscript code, put
parentheses around conditional expressions even if they aren't
syntactically required, unless you really dislike doing this. Note that
the parentheses should go around the entire expression, not the condition.
For instance, instead of
<blockquote><code>
hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br>
(pgls->g.pen_down) ? gs_lineto : gs_moveto);
</code></blockquote>
<p>
use
<blockquote><code>
hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y,<br>
(pgls->g.pen_down ? gs_lineto : gs_moveto));
</code></blockquote>
<h3><a name="Preprocessor_style"></a>Preprocessor</h3>
<h4>Conditionals</h4>
<p>
Using preprocessor conditionals can easily lead to unreadable code, since
the eye really wants to read linearly rather than having to parse the
conditionals just to figure out what code is relevant. It's OK to use
conditionals that have small scope and that don't change the structure or
logic of the program (typically, they select between different sets of
values depending on some configuration parameter), but where possible, break
up source modules rather than use conditionals that affect the structure or
logic.
<h4>Macros</h4>
<p>
Ghostscript code uses macros heavily to effectively extend the rather
weak abstraction capabilities of the C language, specifically in the area of
memory management and garbage collection: in order to read Ghostscript code
effectively, you simply have to learn some of these macros as though they
were part of the language. The current code also uses macros heavily for
other purposes, but we are trying to phase these out as rapidly as possible,
because they make the code harder to read and debug, and to use the
rules that follow consistently in new code.
<p>
Define macros in the smallest scope you can manage (procedure, file, or
<code>.h</code> file), and <code>#undef</code> them at the end of
that scope: that way, someone reading the code can see the definitions
easily when reading the uses. If that isn't appropriate, define them in as
large a scope as possible, so that they effectively become part of the
language. This places an additional burden on the reader, but it can be
amortized over reading larger amounts of code.
<p>
Try hard to use procedures instead of macros. Use "<code>inline</code>"
if you really think the extra speed is needed, but only within a
<code>.c</code> file: don't put inline procedures in <code>.h</code>
files, because most compilers don't honor "<code>inline</code>" and
you'll wind up with a copy of the procedure in every <code>.c</code>
file that includes the <code>.h</code> file.
<p>
If you define a macro that looks like a procedure, make sure it will work
wherever a procedure will work. In particular, put parentheses around every
use of an argument within the macro body, so that the macro will parse
correctly if some of the arguments are expressions, and put parentheses
around the entire macro body. (This is still subject to the problem that an
argument may be evaluated more than once, but there is no way around this in
C, since C doesn't provide for local variables within expressions.)
<p>
If you define macros for special loop control structures, make their uses
look somewhat like ordinary loops, for instance:
<blockquote>
<code>BEGIN_RECT(xx, yy) {</code><br>
... body indented one position ...<br>
<code>} END_RECT(xx, yy);</code>
</blockquote>
<p>
If at all possible, don't use free variables in macros -- that is, variables
that aren't apparent as arguments of the macro. If you must use free
variables, list them all in a comment at the point where the macro is
defined.
<p>
If you define new macros or groups of macros, especially if they aren't
simply inline procedures or named constant values, put some extra effort
into documenting them, to compensate for the fact that macros are
intrinsically harder to understand than procedures.
<h3><a name="Comments"></a>Comments</h3>
<p>
The most important descriptive comments are ones in header files that
describe structures, including invariants; but every procedure or structure
declaration, or group of other declarations, should have a comment. Don't
spend a lot of time commenting executable code unless something unusual or
subtle is going on.
<h3><a name="Naming"></a>Naming</h3>
<p>
Use fully spelled-out English words in names, rather than contractions.
This is most important for procedure and macro names, global variables and
constants, values of <code>#define</code> and <code>enum</code>,
<code>struct</code> and other <code>typedef</code> names, and
structure member names, and for argument and variable names which have
uninformative types like <code>int</code>. It's not very important for
arguments or local variables of distinctive types, or for local index or
count variables.
<p>
Avoid names that run English words together:
"<code>hpgl_compute_arc_center</code>" is better than
"<code>hpgl_compute_arccenter</code>". However, for terms drawn from
some predefined source, like the names of PostScript operators, use a term
in its well-known form (for instance, <code>gs_setlinewidth</code>
rather than <code>gs_set_line_width</code>).
<p>
Procedures, variables, and structures visible outside a single
<code>.c</code> file should generally have prefixes that indicate what
subsystem they belong to (in the case of Ghostscript, <code>gs_</code>
or <code>gx_</code>). This rule isn't followed very consistently.
<h3><a name="Types"></a>Types</h3>
<p>
Many older structure names don't have <code>_t</code> on the end, but
this suffix should be used in all new code. (The <code>_s</code>
structure name is needed only to satisfy some debuggers. No code other than
the structure declaration should refer to it.)
<p>
Declare structure types that contain pointers to other instances of
themselves like this:
<blockquote>
<code>typedef struct xxx_s xxx_t;</code><br>
<code>struct xxx_s {</code><br>
... members ...<br>
<code>xxx_t *</code>ptr_member_name;<br>
... members ...<br>
<code>};</code>
</blockquote>
<p>
If, to maintain data abstraction and avoid including otherwise unnecessary
header files, you find that you want the type <code>xxx_t</code> to be
available in a header file that doesn't include the definition of the
structure <code>xxx_s</code>, use this approach:
<blockquote>
<code>#ifndef xxx_DEFINED</code><br>
<code># define xxx_DEFINED</code><br>
<code>typedef struct xxx_s xxx_t;</code><br>
<code>#endif</code><br>
<code>struct xxx_s {</code><br>
... members ...<br>
<code>};</code>
</blockquote>
<p>
You can then copy the first 4 lines in other header files. (Don't ever
include them in an executable code file.)
<p>
Don't bother using <code>const</code> for anything other than with
pointers as described below. However, in those places where it is necessary
to cast a pointer of type <code>const T *</code> to type
<code>T *</code>, always include a comment that explains why you are
"breaking const".
<h4>Pointers</h4>
<p>
Use <code>const</code> for pointer referents (that is,
<code>const T *</code>) wherever possible and appropriate.
<p>
If you find yourself wanting to use <code>void *</code>, try to
find an alternative using unions or (in the case of super- and subclasses)
casts, unless you're writing something like a memory manager that really
treats memory as opaque.
<h3><a name="Procedures_style"></a>Procedures</h3>
<p> In general, don't create procedures that are private and only called
from one place. However, if a compound statement (especially an arm of
a conditional) is too long for the eye easily to match its enclosing
braces "<code>{...}</code>" -- that is, longer than 10 or 15 lines --
and it doesn't use or set a lot of state held in outer local variables,
it may be more readable if you put it in a procedure.
<h3>Miscellany</h3>
<h4><a name="Local_variables"></a>Local variables</h4>
<p>
Don't assign new values to procedure parameters. It makes debugging very
confusing when the parameter values printed for a procedure are not the
ones actually supplied by the caller. Instead use a separate local
variable initialized to the value of the parameter.
<p>
If a local variable is only assigned a value once, assign it that value at
its declaration, if possible. For example,
<blockquote>
<code>int x = </code>some expression <code>;</code>
</blockquote>
<p>
rather than
<blockquote>
<code>int x;</code><br>
...<br>
<code>x = </code> some expression <code>;</code>
</blockquote>
<p>
Use a local pointer variable like this to "narrow" pointer types:
<blockquote>
<code>int</code><br>
someproc(... <code>gx_device *dev</code> ...)<br>
<code>{<br>
gx_device_printer *const pdev = (gx_device_printer *)dev;</code><br>
...<br>
<code>}</code>
</blockquote>
<p>
Don't "shadow" a local variable or procedure parameter with an inner local
variable of the same name. I.e., don't do this:
<blockquote>
<code>int</code><br>
someproc(... <code>int x</code> ...)<br>
<code>{</code><br>
...<br>
<code> int x;</code><br>
...<br>
<code>}</code>
</blockquote>
<h4><a name="Compiler_warnings"></a>Compiler warnings</h4>
<p>
We want Ghostscript to compile with no warnings. This is a constant
battle as compilers change and new code is added. Work hard to eliminate
warnings by improving the code structure instead of patching over them.
If the compiler can't figure out that a variable is always initialized,
a future reader will probably have trouble as well.
<hr>
<h2><a name="File_structuring"></a>File structuring</h2>
<h3><a name="All_files"></a>All files</h3>
<p>
Keep file names within the "8.3" format for portability:
<ul>
<li>Use only letters, digits, dash, and underscore in file names.
<li>Don't assume upper and lower case letters are distinct.
<li>Put no more than 8 characters before the ".", if any.
<li>If there is a ".", put between 1 and 3 characters after the ".".
</ul>
<p>
For files other than documentation files, use only lower case letters
in the names; for HTML documentation files, capitalize the first letter.
<p>
Every code file should start with comments containing
<ol>
<li>a copyright notice,
<li>the name of the file in the form of an RCS Id:
<blockquote><code>
/* $Id: filename.ext $*/
</code></blockquote>
<p>
(using the comment convention appropriate to the language of the file), and
<li>a summary, no more than one line, of what the file contains.
</ol>
<p>
If you create a file by copying the beginning of another file, be sure to
update the copyright year and change the file name.
<h3><a name="Makefiles"></a>Makefiles</h3>
<p>
Use the extension <code>.mak</code> for makefiles.
<p>
For each
<blockquote><code>
#include "xxx.h"
</code></blockquote>
<p>
make sure there is a dependency on <code>$(xxx_h)</code> in the
makefile. If xxx ends with a "<code>_</code>", this rule still holds,
so that if you code
<blockquote><code>
#include "math_.h"
</code></blockquote>
<p>
the makefile must contain a dependency on "<code>$(math__h)</code>"
(note the two underscores "<code>__</code>").
<p>
List the dependencies bottom-to-top, like the <code>#include</code>
statements themselves; within each level, list them alphabetically. Do
this also with <code>#include</code> statements themselves whenever
possible (but sometimes there are inter-header dependencies that require
bending this rule).
<p>
For compatibility with the build utilities on OpenVMS, always put a space
before the colon that separates the target(s) of a rule from the dependents.
<h3><a name="General_C_code"></a>General C code</h3>
<p>
List <code>#include</code> statements from "bottom" to "top", that is,
in the following order:
<blockquote><ol>
<li>System includes (<code>"xxx_.h"</code>)
<li><code>gs*.h</code>
<li><code>gx*.h</code> (yes, <code>gs</code> and <code>gx</code>
are in the wrong order.)
<li><code>s*.h</code>
<li><code>i*.h</code> (or other interpreter headers that don't start
with "<code>i</code>")
</ol></blockquote>
<h3><a name="Headers"></a>Headers (<code>.h</code> files)</h3>
<p>
In header files, always use the following at the beginning of a header file
to prevent double inclusion:
<blockquote>
{{ Copyright notice etc. }}<br><br>
<code>#ifndef </code><filename><code>_INCLUDED</code><br>
<code>#define </code><filename><code>_INCLUDED</code><br><br>
{{ The contents of the file }}<br><br>
<code>#endif /* </code><filename><code>_INCLUDED */</code>
</blockquote>
<p>
The header file is the first place that a reader goes for
information about procedures, structures, constants, etc., so ensure that
every procedure and structure has a comment that says what it does. Divide
procedures into meaningful groups set off by some distinguished form of
comment.
<h3><a name="Source"></a>Source (<code>.c</code> files)</h3>
<p>
After the initial comments, arrange C files in the following order:
<blockquote><ol>
<li><code>#include</code> statements
<li>Exported data declarations
<li>Explicit externs (if necessary)
<li>Forward declarations of procedures
<li>Private data declarations
<li>Exported procedures
<li>Private procedures
</ol></blockquote>
<p>
Be flexible about the order of the declarations if necessary to improve
readability. Many older files don't follow this order, often without good
reason.
<hr>
<h2><a name="Conventions"></a>Ghostscript conventions</h2>
<h3><a name="Specific_names"></a>Specific names</h3>
<p>
The Ghostscript code uses certain names consistently for certain kinds of
values. Some of the commonest and least obvious are these two:
<h4><a name="code"></a><code>code</code></h4>
<blockquote>
A value to be returned from a procedure:
<table cellpadding=0 cellspacing=0>
<tr valign=top> <td align=right>< 0
<td>
<td>An error code defined in
<a href="../base/gserrors.h">gserrors.h</a>
(or <a href="../psi/ierrors.h">ierrors.h</a>)
<tr valign=top> <td align=right>0
<td>
<td>Normal return
<tr valign=top> <td align=right>> 0
<td>
<td>A non-standard but successful return (which must be documented, preferably with the procedure's prototype)
</table>
</blockquote>
<h4><a name="status"></a><code>status</code></h4>
<blockquote>
A value returned from a stream procedure:
<table cellpadding=0 cellspacing=0>
<tr valign=top> <td align=right>< 0
<td>
<td>An exceptional condition as defined in
<a href="../base/scommon.h">scommon.h</a>
<tr valign=top> <td align=right>0
<td>
<td>Normal return (or, from the "<code>process</code>" procedure, means that more input is needed)
<tr valign=top> <td align=right>1
<td>
<td>More output space is needed (from the "<code>process</code>" procedure)
</table>
</blockquote>
<h3><a name="Structure_type_descriptors"></a>Structure type descriptors</h3>
<p>
The Ghostscript memory manager requires run-time type information for every
structure. (We don't document this in detail here: see the <a
href="Develop.htm#Structure_descriptors">Structure descriptors</a> section
of the developer documentation for details.) Putting the descriptor for a
structure next to the structure definition will help keep the two
consistent, so immediately after the definition of a structure
<code>xxx_s</code>, define its structure descriptor:
<blockquote>
<code>struct xxx_s {</code><br>
... members ...<br>
<code>};</code><br>
<code>#define private_st_xxx() /* in </code><filename><code>.c */\</code><br>
<code> gs_private_st_</code><whatever><code>(st_xxx, xxx_t,\</code><br>
<code> "xxx_t", xxx_enum_ptrs, xxx_reloc_ptrs,\</code><br>
<code> </code>... additional parameters as needed ...<code>)</code>
</blockquote>
<p>
The file that implements operations on this structure
(<filename><code>.c</code>) should then include, near the
beginning, the line:
<blockquote>
<code>private_st_xxx();</code>
</blockquote>
<p>
In much existing code, structure descriptors are declared as
<code>public</code>, which allows clients to allocate instances of the
structure directly. We now consider this bad design. Instead, structure
descriptors should always be <code>static</code>; the implementation
file should provide one or more procedures for allocating instances, e.g.,
<blockquote>
<code>xxx_t *gs_xxx_alloc(P1(gs_memory_t *mem));</code>
</blockquote>
<p>
If it is necessary to make a structure descriptor public, it should be
declared in its clients as
<blockquote>
<code>extern_st(st_xxx);</code>
</blockquote>
<h3><a name="Objects"></a>"Objects"</h3>
<p>
Ghostscript makes heavy use of object-oriented constructs, including
analogues of classes, instances, subclassing, and class-associated
procedures. However, these constructs are implemented in C rather than C++,
for two reasons:
<ul>
<li>The first Ghostscript code was written in 1986, long before C++ was
codified or was well supported by tools. Even today, C++ tools rarely
support C++ as well as C tools support C.
<li>C++ imposes its own implementations for virtual procedures, inheritance,
run-time type information, and (to some extent) memory management.
Ghostscript requires use of its own memory manager, and also sometimes
requires the ability to change the virtual procedures of an object
dynamically.
</ul>
<h4>Classes</h4>
<p>
The source code representation of a class is simply a
<code>typedef</code> for a C <code>struct</code>. See <a
href="C-style.htm#Structures">Structures</a>, above, for details.
<h4>Procedures</h4>
<p>
Ghostscript has no special construct for non-virtual procedures associated
with a class. In some cases, the <code>typedef</code> for the class is
in a header file but the <code>struct</code> declaration is in the
implementation code file: this provides an extra level of opaqueness, since
clients then can't see the representation and must make all accesses through
procedures. You should use this approach in new code, if it doesn't
increase the size of the code too much or require procedure calls for very
heavily used accesses.
<p>
Ghostscript uses three different approaches for storing and accessing
virtual procedures, plus a fourth one that is recommended but not currently
used. For exposition, we assume the class (type) is named
<code>xxx_t</code>, it has a virtual procedure
<code>void (*virtu)(P1(xxx_t *))</code>, and we have a variable
declared as <code>xxx_t *pxx</code>.
<ol>
<li>The procedures are stored in a separate, constant structure of type
<code>xxx_procs</code>, of which <code>virtu</code> is a member. The
structure definition of <code>xxx_t</code> includes a member defined as
<code>const xxx_procs *procs</code> (always named
<code>procs</code>). The construct for calling the virtual procedure is
<code>pxx->procs->virtu(pxx)</code>.
<li>The procedures are defined in a structure of type
<code>xxx_procs</code> as above. The structure definition of
<code>xxx_t</code> includes a member defined as
<code>xxx_procs procs</code> (always named <code>procs</code>).
The construct for calling the virtual procedure is
<code>pxx->procs.virtu(pxx)</code>.
<li>The procedures are not defined in a separate structure: each procedure
is a separate member of <code>xxx_t</code>. The construct for calling
the virtual procedure is <code>pxx->virtu(pxx)</code>.
<li>The procedures are defined in a structure of type
<code>xxx_procs</code> as above. The structure definition of
<code>xxx_t</code> includes a member defined as
<code>xxx_procs procs[1]</code> (always named
<code>procs</code>). The construct for calling the virtual procedure is
again <code>pxx->procs->virtu(pxx)</code>.
</ol>
<p>
Note that in approach 1, the procedures are in a shared constant structure;
in approaches 2 - 4, they are in a per-instance structure that can be
changed dynamically, which is sometimes important.
<p>
In the present Ghostscript code, approach 1 is most common, followed by 2
and 3; 4 is not used at all. For new code, you should use 1 or 4: that way,
all virtual procedure calls have the same form, regardless of whether the
procedures are shared and constant or per-instance and mutable.
<h4>Subclassing</h4>
<p>
Ghostscript's class mechanism allows for subclasses that can add data
members, or can add procedure members if approach 1 or 3 (above) is used.
Since C doesn't support subclassing, we use a convention to accomplish it.
In the example below, <code>gx_device</code> is the root class; it has a
subclass <code>gx_device_forward</code>, which in turn has a subclass
<code>gx_device_null</code>. First we define a macro for all the members
of the root class, and the root class type. (As for structures in general,
classes need a structure descriptor, as discussed in <a
href="#Structures">Structures</a> above: we include these in the examples
below.)
<blockquote><code>
#define gx_device_common\<br>
type1 member1;\<br>
</code>...<code><br>
typeN memberN<br>
<br>
typedef struct gx_device_s {<br>
gx_device_common;<br>
} gx_device;<br>
<br>
#define private_st_gx_device() /* in gsdevice.c */\<br>
gs_private_st_</code><whatever><code>(st_gx_device, gx_device,\<br>
"gx_device", device_enum_ptrs, device_reloc_ptrs,\<br>
</code>... additional parameters as needed ...<code>)
</code></blockquote>
<p>
We then define a similar macro and type for the subclass.
<blockquote><code>
#define gx_device_forward_common\<br>
gx_device_common;\<br>
gx_device *target<br>
<br>
typedef struct gx_device_forward_s {<br>
gx_device_forward_common;<br>
} gx_device_forward;<br>
<br>
#define private_st_device_forward() /* in gsdevice.c */\<br>
gs_private_st_suffix_add1(st_device_forward, gx_device_forward,\<br>
"gx_device_forward", device_forward_enum_ptrs, device_forward_reloc_ptrs,\<br>
gx_device, target)
</code></blockquote>
<p>
Finally, we define a leaf class, which doesn't need a macro because we don't
currently subclass it. (We can create the macro later if needed, with no
changes anywhere else.) In this particular case, the leaf class has no
additional data members, but it could have some.
<blockquote><code>
typedef struct gx_device_null_s {<br>
gx_device_forward_common;<br>
};<br>
<br>
#define private_st_device_null() /* in gsdevice.c */\<br>
gs_private_st_suffix_add0_local(st_device_null, gx_device_null,\<br>
"gx_device_null", device_null_enum_ptrs, device_null_reloc_ptrs,\<br>
gx_device_forward)
</code></blockquote>
<p>
Note that the above example is <strong>not</strong> the actual definition of
the <code>gx_device</code> structure type: the actual type has some
additional complications because it has a finalization procedure. See <a
href="../base/gxdevcli.h">base/gxdevcli.h</a> for the details.
<p>
If you add members to a root class (such as <code>gx_device</code> in
this example), or change existing members, do this in the
<code>gx_device_common</code> macro, not the <code>gx_device</code>
structure definition. Similarly, to change the
<code>gx_device_forward</code> class, modify the
<code>gx_device_forward_common</code> macro, not the structure
definition. Only change the structure definition if the class is a leaf
class (one with no <code>_common</code> macro and no possibility of
subclassing), like <code>gx_device_null</code>.
<h3><a name="Error_handling"></a>Error handling</h3>
<p>
Every caller should check for error returns and, in general, propagate them
to <b>its</b> callers. By convention, nearly every procedure returns an
<code>int</code> to indicate the outcome of the call:
<blockquote><table cellpadding=0 cellspacing=0>
<tr valign=top> <td align=right>< 0
<td>
<td>Error return
<tr valign=top> <td align=right>0
<td>
<td>Normal return
<tr valign=top> <td align=right>> 0
<td>
<td>Non-error return other than the normal case
</table></blockquote>
<p>
To make a procedure generate an error and return it, as opposed to
propagating an error generated by a lower procedure, you should use
<blockquote>
<code>return_error(</code><em>error_number</em><code>);</code>
</blockquote>
<p>
Sometimes it is more convenient to generate the error in one place and
return it in another. In this case, you should use
<blockquote>
<code>code = gs_note_error(</code><em>error_number</em><code>);</code><br>
...<br>
<code>return code;</code>
</blockquote>
<p>
In executables built for debugging, the <code>-E</code> (or
<code>-Z#</code>) command line switch causes <code>return_error</code>
and <code>gs_note_error</code> to print the error number and the source
file and line: this is often helpful for identifying the original cause of
an error.
<p>
See the file <a href="../base/gserrors.h">base/gserrors.h</a> for the error
return codes used by the graphics library, most of which correspond directly
to PostScript error conditions.
<!-- [2.0 end contents] ==================================================== -->
<!-- [3.0 begin visible trailer] =========================================== -->
<hr>
<p>
<small>Copyright © 2000-2006 Artifex Software, Inc. All rights reserved.</small>
<p>
This software is provided AS-IS with no warranty, either express or
implied.
This software is distributed under license and may not be copied, modified
or distributed except as expressly authorized under the terms of that
license. Refer to licensing information at http://www.artifex.com/
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
<p>
<small>Ghostscript version 9.06, 8 August 2012
<!-- [3.0 end visible trailer] ============================================= -->
</body>
</html>
|