Koodausohjeet


Typografia

Luokkien nimet kirjoitetaan isolla alkukirjaimella. Jos luokan nimeen kuuluu useita "sanoja", kirjoitetaan kukin isolla alkukirjaimella. Älä käytä ala-viivoja luokkien nimissä. Kaikkien luokkien nimet alkavat kirjaimilla "Pic".
Esim.
class PicSignature : public PicObject
{ ... 

Muuttujien nimet kirjoitetaan pienellä alkukirjaimella. Jos muuttujan nimeen kuuluu useita "sanoja", kirjoitetaan nämä isolla alkukirjaimella. Älä käytä ala-viivoja muuttujien nimissä.
Esim.

PicSignature *computedSignature = NULLPTR;
for(PICUSHORT i=0; i<MAXLEN; i++){ ... }

Makrot kirjoitetaan kokonaan isoilla kirjaimilla. Jos nimeen kuuluu useita "sanoja", kirjoita ne joko yhteen tai erottele ala-viivoilla. typedef:t kirjoitetaan joko kuten makrot (tai kuten luokan nimi, esim. jos luokan sisäiselle enum:lle määritelty 'julkinen' synonyymi).
Esim.

#define NULLPTR  0
#define MAKE_PICANYCLASS(className, classIdName, base)  ...
typedef unsigned short int PICUSHORT;
typedef PicMyClass::CaseSensitivity PicCaseSensitivity;

Sisennystyyli olkoon suhtellisen vapaa, sisennyksen suuruus olkoon 2 välilyöntiä.
Esim.

void PicVirtClass::assert (const PicVirtObject& found) const
{
  if (found.virtId().isKindOf(*this))
    return;
  found.raiseTypeMismatch(className());
  FATAL_EXIT();
}

Kommentit

Header-tiedostoista ajetaan koodausohjeet HTML-dokumenteiksi, joten käytetään määrämuotoista kommentointia näille. Koodin seassa olevia selventäviä kommentteja ei ajeta HTML:ksi.

Peruskirjasto

Jos ei ole hyvää syytä poiketa käytännöstä, käytä picbase.hxx:ssä määriteltyjä perustyyppejä:
typedef short int          PICSHORT; 
typedef unsigned short int PICUSHORT; 
typedef long int           PICLONG;  
typedef unsigned long int  PICULONG; 
...
typedef PICSHORT PICBOOL; // Type for binary logic with values bTrue and bFalse.
const PICBOOL boolFalse = 0; // False value of binary logic (PICBOOL).
const PICBOOL boolTrue  = 1; // True value of binary logic (PICBOOL).
...

Virheiden käsittely

1. Classify your function:
  - Primitive = Very simplistic functions on the lowest level 
      of your functions. Calls only PicLib's functions and such 
      functions that have no error raising. 
  - Non-master = A non-primitive implementation function used by 
      other more control-oriented functions. Calls primitives
      and other non-masters.
  - Master = Actively controls the execution of the program,
      not called by someone who might want to print the error 
      messages raised under this function. Calls primitives
      and non-masters, possibly masters (but then assumes,
      they print their own error messages).

2. General rule: if you use PicError::isDetected(), then
   put a PicErrorContext at top of your function:

    void MyClass::myFunc(PICBOOL useIt)
    {
        PicErrorContext ecxt;
        ...

3. General rule: if you are able to handle an error, be sure to 
   discard it with PicError::clearCurrent().

4. For primitive functions:
    
    You don't need to check for errors produced by PicLib unless
    you think you can do something about them. 
    If your function fails somehow (bad arguments or something
    else went wrong), raise a descriptive error with ERAISE 
    (or ERAISEFMT) and return. The errors you raise should really 
    be errors, not just a convenient way to indicate, for example, 
    the end of an iteration. 

    E.g.
    void MyClass::myFunc(PICUSHORT percentage)
    {
        if(percentage > 100){
            ERAISE(MyClass, invalidPercentage);
            return;
        }


5. For non-master functions:

    // #define DEBUG_xxx_OFF  !PicMain::globData.params.picXXXDebug()

    At some suitable points check for errors of your callees 
    using PicError::isDetected(). If you detect an error:
       A. do nothing  or
       B. raise a descriptive (more general) error using
            - EHOLD or
            - ERAISE, if the error was surely produced by
              a primitive and DEBUG_xxx_OFF is true

    If your own function fails somehow, raise a descriptive error 
    with ERAISE.

    E.g.
    void MyClass::myFunc(BaseString str)
    {
        PicErrorContext ecxt;

        myOtherFunc(str);   // a primitive function 
        if(PicError::isDetected()){
            if(DEBUG_MY_OFF){
                ERAISE(MyClass, generalFailure);
            }else{
                EHOLD(MyClass, generalFailure);
            }
            return;
        }
        yourFunc1(str);
        yourFunc2(str);
        if(PicError::isDetected()){
            ERAISE(MyClass, generalFailure);
            return;
        }
        ...

5. For master functions:

    At some suitable points check for errors of your callees 
    using PicError::isDetected(). If you detect an error:
        1. print a message of your own if helpful
        2. use FLUSH_ERRORS() (prints the cumulated
            errors messages and clears them).

    If your own function fails somehow, print a descriptive
    error message and return as failed.

    E.g.
    void MyClass::mainFunc(BaseString str)
    {
        PicErrorContext ecxt;

        if(str.isEmpty()){
            INFO_PRINT("Empty string given");
            return;
        }
        myInsertString(str);
        if(PicError::isDetected()){
            INFO_PRINT("Could not insert string " & str & "\n");
            FLUSH_ERRORS();
            return;
        }
        ...