mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-04-16 06:02:36 +02:00
337 lines
11 KiB
Plaintext
337 lines
11 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'.
|
|
|
|
|
|
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 change alters 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/'.
|
|
|
|
4) 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
|