summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-29 18:34:32 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-29 18:34:32 +0000
commit835bd93695c97506e339fb09dc65666a09a6837f (patch)
tree86ed15424b435a85c91aeaea8c444947a5c62ee1 /crawl-ref
parent38058fa3365e63fb431dc86134e2ae113de68e88 (diff)
downloadcrawl-ref-835bd93695c97506e339fb09dc65666a09a6837f.tar.gz
crawl-ref-835bd93695c97506e339fb09dc65666a09a6837f.zip
Added more (suggestions for) coding conventions, I hope that's okay.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3938 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/coding_conventions.txt329
1 files changed, 250 insertions, 79 deletions
diff --git a/crawl-ref/docs/coding_conventions.txt b/crawl-ref/docs/coding_conventions.txt
index 5ca64b06cd..bba1136611 100644
--- a/crawl-ref/docs/coding_conventions.txt
+++ b/crawl-ref/docs/coding_conventions.txt
@@ -1,79 +1,250 @@
-Crawl coding conventions
-========================
-
-Introduction
-------------
-
-This file documents the style conventions currently in use in the crawl
-codebase, as well as the conventions that new and/or modified code should
-conform to. It is explicitly not meant to be a didactic "how to program
-effectively" treatise. That is something best left to books and websites
-and experience.
-
-Conventions
------------
-
-Use 4 spaces to indent, and indent with spaces only (no tabs).
-Use underscores_as_spaces instead of mixedCase. Other conventions are
-pointed out by example, below:
-
-
-// - Global variables are capitalized and underscored.
-// Warning: there are currently many globals which don't do this.
-int Some_Global_Variable;
-
-
-// - Internal functions are prefixed with underscores.
-// Warning: This is a new convention, so much code doesn't follow it.
-static void _remove_from_inventory(item_def* item);
-
-
-// - Functions use underscores_as_spaces, but there are currently
-// a lot of mixedCase functions.
-void destroy_item(item_def* item)
-{
- // - Variables use underscores too.
- int item_weight = /* ... */;
-
- if (item_weight > SOME_LIMIT)
- {
- // - Braces are put on their own line.
- do_something();
- }
-
- // - It's allowable to omit braces, but be careful.
- if (item != NULL)
- _remove_from_inventory(item);
- else
- _something_else();
-}
-
-
-// - There's no convention for class/struct names (yet?)
-class TextDB
-{
- public:
- // - No rules for static member functions; they're not used often anyway.
- static void whatever();
-
- // - Public member functions: named like functions.
- void* get_value();
-
- private:
- // - Internal member functions: also named like functions.
- void _parse_text_file(const char*);
-
- // - Member variables get a prefix.
- DB* m_db;
-
- // - Static member variables get a prefix, too.
- std::vector<DB*> sm_all_dbs;
-};
-
-
-// - But structures tend to use underscores
-struct coord_def
-{
- // - Simple structures don't need the "m_" prefixes
- int x, y;
-};
+Crawl coding conventions
+========================
+
+Introduction
+------------
+
+This file documents the style conventions currently in use in the crawl
+codebase, as well as the conventions that new and/or modified code should
+conform to. It is explicitly not meant to be a didactic "how to program
+effectively" treatise. That is something best left to books and websites
+and experience.
+
+Conventions
+-----------
+
+A) Indenting
+
+Generally, use 4 spaces to indent, and indent with spaces only (no tabs).
+
+Also, empty lines don't need any spacing at all.
+
+If the parameter list of a function runs longer than a line length (80 columns),
+the remaining parameters are indented in the lines below.
+
+static void replace_area( int sx, int sy, int ex, int ey,
+ dungeon_feature_type replace,
+ dungeon_feature_type feature, unsigned mapmask)
+{
+[...]
+}
+
+The same is true when a function is called:
+
+ // place guardian {dlb}:
+ mons_place( MONS_GUARDIAN_NAGA, BEH_SLEEP, MHITNOT, true,
+ sr.x1 + random2( sr.x2 - sr.x1 ),
+ sr.y1 + random2( sr.y2 - sr.y1 ) );
+
+
+There are cases where this is not possible because the parameters themselves
+are too long for that, or because the function is already heavily indented,
+but otherwise, this convention should be followed.
+
+In a switch conditional, the case listings don't have to be indented, though
+the conditional statements should be.
+
+ switch (mons_intel(monster_index(mon)))
+ {
+ case I_HIGH:
+ memory = 100 + random2(200);
+ break;
+ case I_NORMAL:
+ memory = 50 + random2(100);
+ break;
+ case I_ANIMAL:
+ case I_INSECT:
+ memory = 25 + random2(75);
+ break;
+ case I_PLANT:
+ memory = 10 + random2(50);
+ break;
+ }
+
+B) Variable naming
+
+When naming variables, use underscores_as_spaces instead of mixedCase. Other
+conventions are pointed out by example, below:
+
+
+// - Global variables are capitalized and underscored.
+// Warning: there are currently many globals which don't do this.
+int Some_Global_Variable;
+
+
+// - Internal functions are prefixed with underscores.
+// Warning: This is a new convention, so much code doesn't follow it.
+static void _remove_from_inventory(item_def* item);
+
+
+// - Functions use underscores_as_spaces, but there are currently
+// a lot of mixedCase functions.
+void destroy_item(item_def* item)
+{
+ // - Variables use underscores too.
+ int item_weight = /* ... */;
+
+}
+
+
+// - There's no convention for class/struct names (yet?)
+class TextDB
+{
+ public:
+ // - No rules for static member functions; they're not used often anyway.
+ static void whatever();
+
+ // - Public member functions: named like functions.
+ void* get_value();
+
+ private:
+ // - Internal member functions: also named like functions.
+ void _parse_text_file(const char*);
+
+ // - Member variables get a prefix.
+ DB* m_db;
+
+ // - Static member variables get a prefix, too.
+ std::vector<DB*> sm_all_dbs;
+};
+
+
+// - But structures tend to use underscores
+struct coord_def
+{
+ // - Simple structures don't need the "m_" prefixes
+ int x, y;
+};
+
+C) Braces
+
+Braces are always put on their own lines.
+
+ do
+ {
+ curse_an_item(false);
+ }
+ while ( !one_chance_in(3) );
+
+
+If many comparisons are necessary, this can result in a number of nested
+braces. These can sometimes be omitted, as long as the underlying logic isn't
+changed, of course. The following assumes that the conditions are followed by
+single statements.
+
+If both the condition itself and the conditional code are single line
+statements, the braces may be omitted.
+
+ if (item != NULL)
+ _remove_from_inventory(item);
+ else
+ _something_else();
+
+
+Otherwise, place braces.
+
+ if (tran == TRAN_STATUE || tran == TRAN_ICE_BEAST
+ || tran == TRAN_AIR || tran == TRAN_LICH
+ || tran == TRAN_SPIDER) // monster spiders don't bleed either
+ {
+ return (false);
+ }
+
+
+ for ( int i = 0; i < power_level * 5 + 2; ++i )
+ {
+ create_monster(result, std::min(power/50, 6),
+ friendly ? BEH_FRIENDLY : BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG);
+ }
+
+Also place braces if this is only the case because of one or more comment lines.
+
+ for (j = 0; j < num_to_make; j++)
+ {
+ // places items (eg darts), which will automatically stack
+ itrap(beam, i);
+ }
+
+
+In the case of nested if-conditionals, try to combine the conditions, e.g.
+instead of
+
+ if (A)
+ {
+ if (B)
+ do_something();
+ }
+
+use
+
+ if (A && B)
+ do_something();
+
+Place braces as per the conventions above.
+
+Else, whenever if-conditional nesting can't be avoided, always use braces. I
+can't find an example where that isn't already necessary for logical reasons, so
+these should be really rare.
+
+In a row of if-else if-statements or in a switch-case loop, the optional braces
+should be used if the bigger part of statements needs braces for logical reasons
+or because of one of the conventions above. Otherwise, they
+may be omitted.
+
+ if (mons_neutral(monster))
+ {
+ if (coinflip()) // neutrals speak half as often
+ return false;
+
+ prefixes.push_back("neutral");
+ }
+ else if (mons_friendly(monster))
+ prefixes.push_back("friendly");
+ else
+ prefixes.push_back("hostile");
+
+When for-loops are nested and the outer loop has no further statements, the
+braces may be omitted.
+
+ for (int x = 0; x < GXM; x++)
+ for (int y = 0; y < GYM; y++)
+ {
+ if (grd[x][y] == DNGN_LAVA)
+ lava_spaces++;
+ if (grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == NGN_SHALLOW_WATER)
+ water_spaces++;
+ }
+
+The same is true for combined for- and if-conditionals as long as all statements
+fill less than four lines.
+
+ for (i = 0; i < MAX_SHOPS; i++)
+ if (env.shop[i].type == SHOP_UNASSIGNED)
+ break;
+
+If the order of if- and for-conditionals is reversed, however, place braces.
+
+ [...]
+ else if (enhanced < 0)
+ {
+ for (ndx = enhanced; ndx < 0; ndx++)
+ power /= 2;
+ }
+
+
+If there are more than three nested statements with optional bracing, use braces
+to roughly divide them into halves. (See example below.)
+
+Should such nested code be followed by code other than a closing brace,
+leave a free line between them.
+
+ for (int y = 1; y < GYM; ++y)
+ for (int x = 1; x < GXM; ++x)
+ {
+ if (grd[x][y] == feat)
+ return coord_def(x, y);
+ }
+
+ return coord_def(0, 0);
+