The BSD license problem and a trivial solution

FeepingCreature default_357-line at
Sat May 1 05:22:09 PDT 2010

Somebody on IRC mentioned that BSD requires including the license with binaries. So .. is there any reason this won't work?

(Bewarned: code is D1 and not tested)

module std.licenses; // License handling on a per-file basis

import std.stdio, std.string;

string[string] license_texts;
string[] license_order;

// Licenses must be added in order from older to newer.
void addLicense(string name, string text) {
  license_texts[name] = text;
  license_order ~= name;

// If, for instance, this is called with "GPL", it will default to GPLv3; ie. the last version in license_order.
string getFullLicenseName(string prefix) {
  string license_name;
  foreach (name; license_order)
    if (name[0 .. min($, prefix.length)].tolower() == prefix.tolower())
      license_name = name;
  return license_name;

string getLicense(string full_name) {
  return license_texts[full_name];

static this() {
  addLicense("GPLv2", import("LICENSE.GPLv2"));
  addLicense("GPLv3", import("LICENSE.GPLv3"));
  // etc

string[string] file_licenses; // Refer to licenses by name, not text!

void registerFile(string filename, string prefix) {
  file_licenses[filename] = prefix;

void checkLicenses() {
  foreach (key, value; file_licenses)
    if (!getFullLicenseName(value))
      throw new Exception(format("License prefix ", value, " not found in ", license_order));

void printLicenses() {
  string[][string] files_per_license;
  // invert file_licenses
  foreach (key, value; file_licenses)
    files_per_license[getFullLicenseName(value)] ~= key;
  // and print
  foreach (key, value; files_per_license) {
    writefln("The following files are under ", key, ": ", value);
  writefln("The full text of these licenses follows. ");
  foreach (license; files_per_license.keys) {
    writefln(" === ", license, " === ");


1) Add a handler for "--printLicenses" in extern(C) int main. This ensures the text can always be printed.
1.1) Make sure to call checkLicenses beforehand!
2) Public import addLicense and registerFile in object.d
3, optional) Extend the module statement so that `module foo under GPLv2; ` is interpreted as `module foo; static this() { registerFile(__FILE__, "GPLv2"); }`
4, optional) Extend the above system to track what licenses can import what others.

More information about the Digitalmars-d mailing list