Skip to content
This repository has been archived by the owner on Mar 16, 2021. It is now read-only.

Latest commit

 

History

History
127 lines (96 loc) · 4.63 KB

CONTRIBUTING.md

File metadata and controls

127 lines (96 loc) · 4.63 KB

Writing Good Bug Reports

If you think you've found a bug in MrsWatson, please include the logging output from the console when filing a bug report. Ideally, you should also re-run the program with the --verbose option before pasting it into a bug report.

If MrsWatson is generating bad output files, then please run the program with the --error-report option, which will generate a directory on your Desktop. Please zip up the file and include it with your report; this can be very useful in analyzing the audio generated by the program.

Submitting a Patch

So perhaps you've found a bug in MrsWatson, or maybe even added a new feature which you would like to see merged into the codebase. Great! Patches are happily accepted into the project, provided they meet the following conditions:

  • The test suite passes with 100% success rate
    • Also, you get big bonus points for adding new tests, both in the case of bugfixes or new features.
  • The code is properly formatted, and meets the project's style and readability conventions.
  • In the case of a new feature, it provides something which is useful to the broader community.

All GitHub pull requests are tested with AppVeyor and Travis. If your PR does not pass these builds, then it will not be merged. Lastly, it should be noted that patches are only accepted via GitHub on the project's official homepage. Patches sent as diffs over email, with carrier pigeons, etc, should be resubmitted as GitHub pull requests, since this offers the greatest public visibility.

Coding Style Conventions

MrsWatson is indented using clang-format 3.8 with the default LLVM style. Code formatting is enforced using a Travis CI configuration. If this job fails with your pull request, simply format the files and resubmit:

clang-format -style=LLVM -i path/to/file.c

Regarding naming conventions, CamelCase is used for class and variable names, with uppercase used for types and lowercase for instances.

Coding Conventions

MrsWatson is written in C, although there is a small amount of C++ code used to communicate with VST plug-ins. Please do not expand the amount of C++ code in the project unless strictly necessary (and the same goes for other languages such as Obj-C).

That said, MrsWatson uses a python-like meta-class structure which you should adhere to. Also, long and readable names are preferred (which is in contrast to much C code on the internet).

Meta-Classes

Classes in MrsWatson are simple structs with some associated functions that are able to operate on them. A naming convention is used to associate the class with the associated functions. Each of these functions takes in a "self" argument as its first parameter, just like in Python. Also like Python, there are no private members in the structs, so a leading underscore is used to indicate that a member should not be directly accessed.

Instead of passing raw pointers throughout the source code, typedefs are used to make the code easier to understand. Thus, a sample class might look like this:

typedef struct {
  int foo;
  char _bar;
  char* baz;
} MyClassMembers;
typedef MyClassMembers* MyClass;

Each class should provide a constructor function and a destructor function so that the caller does not need to manually allocate and free the associated memory. By convention, these functions should be prefixed with "new" and "free". Continuing our example:

MyClass newMyClass(void) {
  MyClass result = (MyClass)malloc(sizeof(MyClassMembers));
  result->foo = 0;
  result->_bar = 'a';
  result->baz = NULL;
  return result;
}

void freeMyClass(MyClass self) {
  if (self != NULL) {
    free(self->baz);
    free(self);
  }
}

Any member functions for this class should begin with the class name. This begins to get a little verbose, but at least it makes the code easy to understand. Continuing our example:

char myClassGetBar(MyClass self) {
  return self->_bar;
}

size_t myClassBazLength(MyClass self) {
  return self->baz != NULL ? strlen(self->baz) : 0;
}

The result is a convention that allows one to write code like this:

MyClass whatever = newMyClass();
if(myClassBazLength(whatever)) {
  char ch = myClassGetBar(whatever);
}
freeMyClass(whatever);