File: coding-guidelines.txt

package info (click to toggle)
vice 3.7.1%2Bdfsg1-2
  • links: PTS
  • area: contrib
  • in suites: bookworm
  • size: 49,876 kB
  • sloc: ansic: 431,530; cpp: 35,357; sh: 9,747; makefile: 7,010; perl: 1,822; yacc: 1,197; lex: 589; sed: 184; objc: 115; xml: 36
file content (512 lines) | stat: -rw-r--r-- 15,067 bytes parent folder | download | duplicates (2)
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
VICE project coding guidelines
==============================

This document is intended to set some guidelines for people wanting to
contribute code to the VICE project.

There are two distinct parts to the VICE source code, the architecture code
parts which are located in src/arch, and the common code parts which are
located everywhere in src except in src/arch.

The common code is used by all supported architectures and therefor needs to be
as portable as possible.

To achieve this portability, and to keep the codebase tidy and clean, some
guidelines have to be followed.

Project Folders Hierarchy Descriptions
--------------------------------------

Here are short descriptions of the project code folders and their functions:

generally:

- All code in the root of the tree is common code that contains no architecture
  specific parts.

- 3rd party libraries and headers which have been pulled into the sourcetree
  live in src/lib/ . Files in this directory tree do not have to follow the
  codestyle lined out here, as they could be replaced/updated at any time.

- Architecture specific code lives in src/arch/shared.

- Code that is specific to a (G)UI should live in src/arch/<gui>.

in detail:

build
 beos
 github-actions
 macOS
 mingw
  docker
  frankenvice

data
 C128
 C64
 C64DTV
 CBM-II
 common
 DRIVES
 GLSL
 PET
 PLUS4
 PRINTER
 SCPU64
 VIC20

doc
 building
 html
  fonts
  images
 readmes
 vim
  ftdetect
  syntax

m4                          - m4 code used by the buildsystem

src                         - common code
 arch                       - architecture specific code for various platforms (win, unix, amigaos, etc)
  gtk3                      - gtk3 ui
   data
    macos
    unix
    win32
   joystickdrv              - gtk joystick handling
   novte                    - gtk monitor console
   Resources
   widgets
    base
  headless                  - headless "ui"
  sdl                       - sdl1 and sdl2 ui
   Resources
  shared
   hwsiddrv                 - drivers for hardware SID cards, mostly using direct I/O and thus obsolete
   iodrv
   mididrv
   samplerdrv
   socketdrv
   sounddrv                 - framework specific sound drivers
  systemheaderoverride      - headers that override headers usually provided by system libraries
   gtk

 buildtools

 c128                       - commodore 128 specific code
 c64                        - c64 specific code
  cart                      - c64 cartridge specific code
 c64dtv                     - c64 direct tv specific code
 cbm2                       - Commodore CBM-II computer emulator
  cart
 pet                        - pet computer specific emulation code
 plus4                      - commodore plus4 specific code
  cart
 scpu64
 vic20                      - commodore vic20 specific code
  cart

 core                       - various chip emulations (CIA, VIA and Cart specific chip emulations)
  rtc                       - real time clock emulation used in some devices (fd2000/4000, ide64, etc..)
 crtc                       - CRTC emulation
 resid                      - cycle exact sid engine (made by dag lem)
 resid-dtv
 sid                        - SID chip interface and emulation for fallback sid engine (fastsid)
 vdc                        - MOS8563 VDC emulation
 vicii                      - almost cycle exact VICII emulation code for x64, x128, xcbm2, and x64dtv
 viciisc                    - more cycle exact then vicii code emulation used in x64sc and xscpu64

 diag

 diskimage                  - various file types support (.d64, .d81, etc..)
 imagecontents              - disk and tape directory interface

 iecbus                     - iec bus handling
 parallel                   - ieee488 emulation code
 serial                     - iec interface code and real iec access (for using real drives on usb with vice)

 drive                      - various disk drive hardware emulations and bus systems used (iec or ieee)
  iec
   c64exp
   plus4exp
  iec128dcr
  iecieee
  ieee
  tcbm
 vdrive                     - virtual drives code, opposed to "true drive emulation" found in drive folder

 fileio                     - for accessing prg files directly
 fsdevice                   - for host filesystem as if an iec device is used

 hvsc
 joyport
 monitor                    - code for built-in monitor
 
 datasette
 tape                       - tape drive specific emulation and T64 support
 tapeport

 userport                   - userport device emulation code

 raster                     - raster-based video chip emulation
 video                      - pixel framebuffer to physical screen interface code

 lib                        - anything related to external libraries (ffmpeg codec, etc.. see above)
  linenoise-ng
  p64

 tools
  cartconv
  petcat

 gfxoutputdrv               - screen capture (image and video drivers)
 printerdrv                 - specific printer type emulation and drivers
 rs232drv                   - rs232 communication and modem code for interfacing with arch specific drivers


Cosmetic guidelines for all code
--------------------------------

To keep the code tidy and easy to follow please read the following statements:


- Don't use C++ style comments in C code (// comment), use C-style comments
  instead (/* comment */). This goes for C99 code as well.

  You may use the ./checkstyle.sh script to find dangling c++ comments:

  $ ./checkstyle.sh comments

- We strictly indent by 4 spaces. Don't use mixtures of tabs and spaces as
  indentation, using 4 spaces per level will make the code look the same no
  matter what editor you use.

  You may use the checkstyle.sh script to find dangling tabs:

  $ ./checkstyle.sh tabs

- Avoid trailing whitespace. Many editors can show this and remove this.

  You may use the checkstyle.sh script to find trailing whitespace:

  $ ./checkstyle.sh whitespace

- Refrain from using any non ASCII characters in source files, unless absolutely
  necessary. Previously a common trap were copyright headers - make sure to
  use latin letters only to write your name etc. or in other words: such chars
  should not be used anywhere, except in a few selected (usually translation
  related) files that contain tables of strings.
  The reason for this is that various tools get confused or even choke on any-
  thing that isnt the encoding they expect (and plain ascii always works). It
  also ensures that all files can be edited by anyone at any time without intro-
  ducing weird side effects.
  On a *nix system you may use the "file" command to check the files you
  changed, normally it should always say "ASCII text" (not ISO-8859, and
  definately not UTF-8 Unicode).

  current exceptions from this rule are:

  src/infocontrib.h: ISO-8859 (generated file)

  Keep in mind that editing the translation related files need special care,
  make sure not to mess up the file by somehow converting the encoding!

  You may use the findhacks.sh script in src/ to check all sourcefiles and find
  any that contain non ascii characters:

  $ ./findhacks.sh encoding

- Use the types in <stdint.h> for fixed-width types, so `uint8_t` rather than
  `BYTE`, `uint16_t` for `WORD` and `uint32_t` for `DWORD`.

- Generally put the opening brace of a block at the end of the line ("cuddling"
  braces style), except at the beginning of a function, ie:

  void foo(int bar)
  {
      if (bar) {
          /* ... */
      }
  }


- No variable declarations after the first line of code, some compilers
  just can't handle it.


- One variable declaration per line, and especially don't mix plain types with
  pointers.

  Don't do this:

    int foo, bar, *huppel;

  Do this:
    int foo;
    int bar;
    int *huppel;

  Might look short and clever, but as soon as you want to change a single type,
  you'll either screw them all up, or have to split them anyway. Just don't.


  New block-level declarations are fine:

    if (foo) {
        int bar = 0;
        /* code using bar */
    }

  Perfectly valid even in C89, if a compiler can't handle this, get a proper
  compiler.

- For 'if' and 'for' always use braces.
  examples:

    if (foo) {
        ...
    }

    if (foo) {
        ...
    } else {
        ...
    }

    for (i = 0; i < 255; i++) {
        ...
    }

- A keyword should be followed by a space, so:
    if (foo == 0) { ... }
  not
    if(foo == 0) { ... }

  Exception: the sizeof operator, using sizeof as a "function" on a type should
             not use spaces, ie: sizeof(int), however using sizeof on an object
             should use spaces (ie: int *i; sizeof *i)

- Binary operators: use spaces around binary operators:
    int i = 1 + 2;
    unsigned int i <<= 3;

  But please don't use them with when accessing members of an object:
    foo->bar, not foo -> bar.

- Unary operators:
  Don't use spaces when using unary operators:
    ~0 is fine,
    ~ 0 isn't.

- Use boolean logic only when the context is clear and the thing tested can
  actually be considered boolean:

  Basically:
    `if (!strcmp(a b))` is WRONG since strcmp() returns three different values,
    0 when equal (which is what the ! tests against), < 0 when a < b, and
    > 0 when b > a.
    So please use `if (strcmp(a, b) == 0)`, a little more typing, but much more
    clear.

    We also seem to have a lot of functions returning either 0 on success, or
    -1 on error. And a lot of code using boolean logic on the return value.
    Please don't. Unfortunately this is so wide spread in the VICE code it's
    hard to fix.

- Use braces even when they are not really required, it makes expressions
  easier to read and allows to use advanced highlighting in the editor, ie

  if ((a + b) && (c != d)) {
      /* ... */
  }

    instead of

  if (a + b && c != d) {
      /* ... */
  }

- No 'clever' while/do trickery, unless required for preprocessor code. The
  following looks clever:

    while (*s++ != '\0');

  But this is clearer and will generate the same object code:

    while (*s != '\0') {
        s++;
    }

- To give the code a consistent look use specifiers named with prefixes
  like in the following examples:

    struct foobar_s {
        ...
    };

    typedef ... foobar_t;

    enum stuff_e {
        ...
    };

    union many_u {
        ...
    };

  Of course combinations may be used:

    typedef struct foobar_s {
        ...
    } foobar_t;

  Exceptions are basic type like BYTE, WORD, DWORD and code that follows a
  coding style of a certain architecture, e.g. UI code.

- Preprocessor macros which define constants or enumeration values should
  be written in capital letters.

   #define FORTYTWO 42

   typedef numbers_e {
       NUM_ZERO,
       NUM_ONE
   } numbers_t;

- Properly document any fall through in switch/case constructs:

    switch (foo) {
        case 42:    /* fall through */
        case 69:
            hehe();
            break;
    }


Symbols in ifdefs
-----------------

- If tests for a certain (G)UI are needed, they can use the following symbols.
  No other symbols should be defined to "shortcut" certain combinations!

  USE_SDLUI
  USE_SDL2UI
  USE_GTK3UI
  USE_HEADLESSUI

  Remember this kind of tests should ideally not occur anywhere in common code -
  but if they can not be avoided, they should always come with a comment that
  tells why this test exists.

- For tests for a certain architecture/operating system the build system defines
  some symbols. No other symbols should be used for this, in particular not the
  various things defined by compilers or system libraries. Eg do not use
  "_WIN32" when you need to check for "is this windows?", use "WINDOWS_COMPILE"
  instead.

  The architecture symbols are nested in a hierarchic way:

  WINDOWS_COMPILE           - compiling for windows (32bit AND 64bit)
    WIN64_COMPILE           - compiling for 64bit windows
  UNIX_COMPILE              - any *nix system
    LINUX_COMPILE
    MACOS_COMPILE
    BSD_COMPILE
      FREEBSD_COMPILE
      DRAGONFLYBSD_COMPILE
      NETBSD_COMPILE
      OPENBSD_COMPILE
  BEOS_COMPILE
    HAIKU_COMPILE

  Remember this kind of tests should ideally not occur anywhere in common code -
  but if they can not be avoided, they should always come with a comment that
  tells why this test exists.

- When using headers which are tested for in configure.proto don't assume they
  exist, use the #ifdef HAVE_*_H instead.

   #ifdef HAVE_SYS_TYPES_H
   #include <sys/types.h>
   #endif

  you can look at src/config.h to see which symbols are available

- When adding header files use VICE_*_H as shown in the following example:

   #ifndef VICE_RS232_H
   #define VICE_RS232_H

   ...code...

   #endif


Common code guidelines
----------------------

Many different compilers may be used to compile the common code parts, although
in practise this will be GCC, Clang or MSVC.

- There should be no compiler specific hacks anywhere and no ifdefs checking
  for specific compilers. The only exception to this rule is the global vice.h.
  The same is true for CPU/Arch specific checks.

  There are still some of these compiler specific hacks dangling around, all of
  which are subject for removal. Do not add any new ones :)

  You can find such things using ./src/findhacks.sh ccarchdep

- Generally no arch specific hacks and ifdefs should be present in common code.
  All arch specific code should be abstracted into functions which then live in
  src/arch/shared. Code that is specific to a GUI should live in src/arch/<gui>.

  When a platform specific ifdef can not be avoided in common code, it should
  always come with a comment that explains why exactly that ifdef exists and
  what the respective portion of code is supposed to do.

  Since this rule did not exist in the past, there is still a lot of arch 
  specific code around elsewhere that needs to be moved - this is no excuse for
  ignoring the rule when writing new code however.

  You can find such thing using: ./src/findhacks.sh archdep


Documentation
-------------

Please add documentation to code you add or alter.

We use Doxygen to document our code, add docblocks for each public function or
data structure, at a minimum. Adding documentation is boring and the discipline
to do that is even harder, but it'll help out your fellow (future) devs and
probably even you after not working on a piece of code for some time. (Also
see Doxygen-Howto.txt)

This also applies to the user manual - when you are adding new features, please
document it in vice.texi (see Documentation-Howto.txt)


Adding new files to the svn repo
--------------------------------

When adding a *nix script file use the following svn properties:

svn:eol-style   LF
svn:mime-type   text/plain
svn:executable  *

When adding a windows/dos batch file use the following svn properties:

svn:eol-style   CRLF
svn:mime-type   text/plain
svn:executable  *

When adding a non-text file use only the correct mime-type.

For all other files use the following svn properties:

svn:eol-style   native
svn:mime-type   text/plain