mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-04-07 01:13:50 +02:00
* Added a section concerning default configuration files to the 'PULL REQUEST CHECKLIST' section of 'CODINGSTYLE'.
349 lines
12 KiB
Plaintext
349 lines
12 KiB
Plaintext
This is the CODINGSTYLE file for the Rivendell package.
|
|
|
|
OVERVIEW:
|
|
This file, CODINGSTYLE, describes the coding style guidelines for writing
|
|
new code, how to submit patches to be incorporated into the official
|
|
Rivendell Git repository, and other code related information. General info
|
|
on the Rivendell project can be found at the http://www.rivendellaudio.org/
|
|
web page and also in the 'README' and 'INSTALL' files.
|
|
|
|
The code style used for Rivendell is a somewhat idiosyncratic mixture of
|
|
the style generally used for Qt C++ programs combined with the classic UNIX
|
|
C style. Some of the specifics include:
|
|
|
|
|
|
LINE LENGTH:
|
|
Should not be longer than 78 characters unless doing so would severely
|
|
compromise the readability of the code. Where it is necessary to break a
|
|
line, it should be done at a point that preserves maximum clarity and ease
|
|
of reading.
|
|
|
|
Good:
|
|
*report+=QString(" ")+
|
|
logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
|
|
QString().sprintf(" - cart %06d [",logLine(i)->cartNumber())+
|
|
q->value(1).toString()+"] "+QObject::tr("is not playable")+"\n";
|
|
|
|
Bad:
|
|
*report+=QString(" ")+logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+QString().sprintf(" - cart %06d [",logLine(i)->cartNumber())+q->value(1).toString()+"] "+QObject::tr("is not playable")+"\n";
|
|
|
|
|
|
INDENTATION:
|
|
Should be two spaces per level. This helps to keep the line length down.
|
|
|
|
Good:
|
|
if(to_line<0) {
|
|
to_line=size();
|
|
for(int i=from_line;i<size();i++) {
|
|
if(logLine(i)->timeType()==RDLogLine::Hard) {
|
|
to_line=i;
|
|
i=size();
|
|
if(sched_time!=NULL) {
|
|
*sched_time=logLine(i)->startTime(RDLogLine::Logged);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Bad:
|
|
if(to_line<0) {
|
|
to_line=size();
|
|
for(int i=from_line;i<size();i++) {
|
|
if(logLine(i)->timeType()==RDLogLine::Hard) {
|
|
to_line=i;
|
|
i=size();
|
|
if(sched_time!=NULL) {
|
|
*sched_time=logLine(i)->startTime(RDLogLine::Logged);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
CURLY BRACES:
|
|
Conditional statements (such as 'if' and 'for') should *always* use curly
|
|
braces, even where the affected block is but one line long. The opening
|
|
brace should be on the same line as the conditional and the closing one on
|
|
a line by itself. This style greatly facilitates debugging, allowing a
|
|
single line to be provisionally commented out or additional lines to be
|
|
provisionally added without making the enclosing conditional syntactically
|
|
invalid.
|
|
|
|
Good:
|
|
if(i==12) {
|
|
printf("i is equal to twelve!\n");
|
|
}
|
|
|
|
Bad:
|
|
if(i==12)
|
|
printf("i is equal to twelve!\n");
|
|
|
|
|
|
PADDING WHITESPACE:
|
|
Wherever possible, there should be no whitespace between constants/variables
|
|
and operators. This helps to keep the line length down.
|
|
|
|
Good:
|
|
for(int i=from_line;i<size();i++) {
|
|
if(logLine(i)->timeType()==RDLogLine::Hard) {
|
|
to_line=i;
|
|
}
|
|
}
|
|
|
|
Bad:
|
|
for(int i = from_line; i < size(); i++) {
|
|
if(logLine(i)->timeType() == RDLogLine::Hard) {
|
|
to_line = i;
|
|
}
|
|
}
|
|
|
|
|
|
CLASS NAMES:
|
|
Should have the initial letter of each word capitalized, e.g. 'ThisIsMyClass'.
|
|
If the class is part of the librd convenience library (in 'lib/'), the name
|
|
should be prefaced with the uppercase letters 'RD', e.g. 'RDThisIsMyClass'.
|
|
|
|
|
|
METHOD NAMES:
|
|
Public method names as well as signal and slot method names should follow
|
|
the general style used by Qt. A special convention for Rivendell is to
|
|
reserve names beginning with an uppercase letter for private methods only.
|
|
|
|
Good:
|
|
class RDLogPlay
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
RDLogPlay(int id,RDEventPlayer *player,QObject *parent=0);
|
|
QString serviceName() const;
|
|
void setServiceName(const QString &svcname);
|
|
|
|
private slots:
|
|
void transTimerData();
|
|
void graceTimerData();
|
|
|
|
signals:
|
|
void renamed();
|
|
void reloaded();
|
|
void transportChanged();
|
|
|
|
private:
|
|
bool StartEvent(int line,RDLogLine::TransType trans_type,int trans_length,
|
|
RDLogLine::StartSource src,int mport=-1,int duck_length=0);
|
|
bool StartAudioEvent(int line);
|
|
};
|
|
|
|
Bad:
|
|
class RDLogPlay
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
RDLogPlay(int id,RDEventPlayer *player,QObject *parent=0);
|
|
QString servicename() const;
|
|
void set_service_name(const QString &svcname);
|
|
|
|
private slots:
|
|
void TransTimerData();
|
|
void grace_timer_data();
|
|
|
|
signals:
|
|
void RENAMED();
|
|
void Reloaded();
|
|
void transport_changed();
|
|
|
|
private:
|
|
bool startEvent(int line,RDLogLine::TransType trans_type,int trans_length,
|
|
RDLogLine::StartSource src,int mport=-1,int duck_length=0);
|
|
bool startAudioEvent(int line);
|
|
};
|
|
|
|
|
|
VARIABLE NAMES:
|
|
*All* variables should be lowercase only, with uppercase being reserved for
|
|
class and method names. Words should be separated by underscores.
|
|
|
|
Good:
|
|
int log_position_number=1;
|
|
|
|
Bad:
|
|
int logPositionNumnber=1;
|
|
|
|
Class variables should be prefaced with a short base name that is common to
|
|
all, followed by an underscore. For example, the class 'MyClass' might use
|
|
'myclass_', as in 'myclass_foo1', 'myclass_foo2', etc. Local variables
|
|
(including function parameter names) should be kept short, preferably a
|
|
single word.
|
|
|
|
|
|
SQL STATEMENTS:
|
|
When embedding SQL statements in code, the following guidelines should be
|
|
followed:
|
|
|
|
1) All table and field names are uppercase-only, while SQL operators
|
|
should be all lowercase.
|
|
|
|
Good:
|
|
sql="select FIELD1,FIELD2 from MY_TABLE where ID=2";
|
|
|
|
Bad:
|
|
sql="SELECT FIELD1,FIELD2 FROM MY_TABLE WHERE ID=2";
|
|
|
|
2) Long or complex SQL statements should be broken into multiple lines in
|
|
a manner to enhance the readability of both C++ and SQL. For 'select'
|
|
queries that return more than two fields per row, each field should be
|
|
commented with its ordinal number to assist in determining the
|
|
appropriate value to give to 'RDSqlQuery::value()' for referencing
|
|
the fields.
|
|
|
|
Good:
|
|
sql=QString("select ")+
|
|
"CART.TITLE,"+ // 00
|
|
"CART.ARTIST,"+ // 01
|
|
"CART.PUBLISHER,"+ // 02
|
|
"CART.COMPOSER,"+ // 03
|
|
"CART.USAGE_CODE,"+ // 04
|
|
"CUTS.ISRC,"+ // 05
|
|
"CART.ALBUM,"+ // 06
|
|
"CART.LABEL,"+ // 07
|
|
"CUTS.ISCI,"+ // 08
|
|
"CART.CONDUCTOR,"+ // 09
|
|
"CART.USER_DEFINED,"+ // 10
|
|
"CART.SONG_ID,"+ // 11
|
|
"CUTS.DESCRIPTION,"+ // 12
|
|
"CUTS.OUTCUE "+ // 13
|
|
"from CART left join CUTS "+
|
|
"on CART.NUMBER=CUTS.CART_NUMBER where "+
|
|
"CUTS.CUT_NAME=\""+RDEscapeString(button->cutName())+"\"";
|
|
|
|
Bad:
|
|
sql="select CART.TITLE,CART.ARTIST,CART.PUBLISHER,CART.COMPOSER,CART.USAGE_CODE,CUTS.ISRC,CART.ALBUM,CART.LABEL,CUTS.ISCI,CART.CONDUCTOR,CART.USER_DEFINED,"+ CART.SONG_ID,CUTS.DESCRIPTION,CUTS.OUTCUE from CART left join CUTS on CART.NUMBER=CUTS.CART_NUMBER where CUTS.CUT_NAME=\""+RDEscapeString(button->cutName())+"\"";
|
|
|
|
|
|
SCHEMA CHANGES:
|
|
Changes that alter the schema of the database must include:
|
|
|
|
A) Incrementation of the 'RD_VERSION_DATABASE' value in 'lib/dbversion.h'.
|
|
|
|
B) Code that implements the schema change, in the
|
|
'utils/rddbmgr/updateschema.cpp' file.
|
|
|
|
C) Code the implements an exact, perfect reversal of the schema change,
|
|
in the 'utils/rddbmgr/revertschema.cpp' file.
|
|
|
|
D) Updating of the schema map in the 'MainObject::InitializeSchemaMap()'
|
|
method in the 'utils/rddbmgr/schemamap.cpp' file. (See the comment at
|
|
the top of the method definition for details).
|
|
|
|
E) Update the table documentation appropriately in 'docs/tables/'.
|
|
|
|
F) [VERY IMPORTANT] - Document the changes to the schema in your
|
|
'ChangeLog' entry, including the new value of 'RD_VERSION_DATABASE'.
|
|
|
|
|
|
FONT MANGEMENT:
|
|
All fonts used in Rivendell are managed by the RDFontEngine class, which
|
|
provides them on the basis of abstract "roles" so as to provide consistency
|
|
across the entire set of modules. See the file 'docs/apis/fonts.pdf' for
|
|
a detailed description of this sub-system, including screenshot examples.
|
|
|
|
|
|
WRITING TO THE SYSLOG:
|
|
Rivendell makes extensive use of the syslog(3) system found on all
|
|
POSIX-compliant systems. Sending messages to the syslog should almost
|
|
always be done by means of the following method in 'RDApplication':
|
|
|
|
void RDApplication::syslog(int priority,const char *format,...)
|
|
|
|
The exception to the above is when the application context does not
|
|
include a global RDApplication object --e.g. in caed(8). For those
|
|
cases, the following static RDApplication method should be used:
|
|
|
|
void RDApplication::syslog(RDConfig *c,int priority,const char *format,...)
|
|
|
|
For a discussion of the parameters of these methods, see the syslog(3) man
|
|
page. The 'priority' parameter should be one of the following values:
|
|
|
|
LOG_ERR - Indicates that a fatal error has occurred; 'fatal' meaning
|
|
that the program is unable to continue and will now exit.
|
|
|
|
LOG_WARNING - Indicates that a non-fatal error has occured; meaning
|
|
that the program will continue to operate, but with
|
|
possibly significant operational degradation. This would be
|
|
appropriate for things like failure to connect to an
|
|
external switcher or other device.
|
|
|
|
LOG_INFO - Information useful for tracking operational state --e.g.
|
|
a cart play-out has begun, a new Rivendell log has been
|
|
loaded, etc.
|
|
|
|
LOG_DEBUG - Information useful for tracking or verifying Rivendell
|
|
software internal state. These messages will not normally
|
|
be seen by users, but can be made visible to allow for
|
|
program debugging.
|
|
|
|
NOTE: A 'facility' value should *not* be included in the 'priority'
|
|
argument. The appropriate 'facility' value, as determined by the
|
|
'SyslogFacility=' directive in rd.conf(5), will be added automatically.
|
|
|
|
|
|
CONTRIBUTING CHANGES:
|
|
The master code repository for Rivendell resides at GitHub, and can be
|
|
found at:
|
|
|
|
https://github.com/ElvishArtisan/rivendell
|
|
|
|
Changes should be submitted in the form of a pull request [PR] against
|
|
the 'master' branch. Information about drafting and submitting PRs can
|
|
be found at:
|
|
|
|
https://help.github.com/en/articles/about-pull-requests
|
|
|
|
|
|
PULL REQUEST CHECKLIST:
|
|
Before submitting a pull request, the following guidelines should be
|
|
completed:
|
|
|
|
1) The code should compile without errors or warnings [the '-Werrors' switch
|
|
for gcc(1) is your friend here!].
|
|
|
|
2) Add an entry to the 'ChangeLog' file at the base of the Rivendell source
|
|
code tree, describing your changes. The format of the ChangeLog file has
|
|
the most recent changes at the bottom of the file. Entries start with a
|
|
date stamp and have a format like:
|
|
|
|
YYYY-MM-DD NAME <EMAIL>
|
|
* Description of change
|
|
|
|
For example:
|
|
2007-02-23 John Coder <coder@example.com>
|
|
* Modified the code in 'lib/rdimport_audio.cpp' to use the
|
|
'RDCart::setMetadata()' and 'RDCut::setMetadata()' methods.
|
|
|
|
3) If your changes add, remove or change the behavior of one or more
|
|
configuration entries in rd.conf(5), update the default configuration
|
|
file ('conf/rd.conf-sample') accordingly. Similiarly, for PyPAD scripts,
|
|
be sure to update the corresponding '<plugin-name>-exemplar' files.
|
|
|
|
4) If your changes alter any user-visible aspect (UI or behavior), update
|
|
the user documentation appropriately. The documentation is written
|
|
in DocBook 5 markup, and can be found at the following locations in
|
|
the source tree:
|
|
|
|
Operations Guide - 'docs/opsguide/'
|
|
|
|
Manual pages - 'docs/manpages/'
|
|
|
|
Internal and public APIs - 'docs/apis/'.
|
|
|
|
5) If you wish your work to be mentioned in the 'Credits' list displayed in
|
|
rdadmin(1), add or modify the appropriate entry in the 'AUTHORS' file.
|
|
Entries should be sorted by surname, then christian name of the author.
|
|
|
|
|
|
QUESTIONS:
|
|
Questions about coding style, or indeed any aspect of Rivendell development,
|
|
are welcomed on the Rivendell-prog mailing list. Subscription information
|
|
and list archives are available at:
|
|
|
|
http://caspian.paravelsystems.com/mailman/listinfo/rivendell-prog
|