vice  3.7.1
About: VICE is the Versatile Commodore (64/128/VIC20/PET/PLUS4/CBM-II) Emulator (X11).
  Fossies Dox: vice-3.7.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

No Matches
coding guidelines
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/. 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 ./ script to find dangling c++ comments: $ ./ 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 script to find dangling tabs: $ ./ tabs - Avoid trailing whitespace. Many editors can show this and remove this. You may use the script to find trailing whitespace: $ ./ 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 script in src/ to check all sourcefiles and find any that contain non ascii characters: $ ./ encoding - Use the types in 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 #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/ 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/. 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/ 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