const struct license_info licenses[] = {
{ "LGPLv2+", "LGPL",
+ "GNU LGPL version 2 (or later)",
{ "gnu lesser general public license",
"version 2",
"or at your option any later version"
}
},
{ "LGPLv2", "LGPL",
+ "GNU LGPL version 2",
{ "gnu lesser general public license",
"version 2",
NULL
}
},
{ "LGPLv3", "LGPL",
+ "GNU LGPL version 3",
{ "gnu lesser general public license",
"version 3",
NULL
}
},
{ "LGPL", "LGPL",
+ "GNU LGPL",
{ "gnu lesser general public license",
NULL,
NULL
}
},
{ "GPLv2+", "GPL",
+ "GNU GPL version 2 (or later)",
{ "gnu general public license",
"version 2",
"or at your option any later version"
}
},
{ "GPLv2", "GPL",
+ "GNU GPL version 2",
{ "gnu general public license",
"version 2",
NULL
}
},
{ "GPLv3", "GPL",
+ "GNU GPL version 3 (or later)",
{ "gnu general public license",
"version 3",
NULL
}
},
{ "GPL", "GPL",
+ "GNU GPL",
{ "gnu general public license",
NULL,
NULL
}
},
{ "BSD-3CLAUSE", "BSD",
+ "3-clause BSD license",
{ "redistributions of source code must retain",
"redistributions in binary form must reproduce",
"endorse or promote"
}
},
{ "BSD-MIT", "MIT",
+ "MIT (BSD) license",
{ "without restriction",
"above copyright notice",
"without warranty"
}
},
{ "CC0", "CC0",
+ "CC0 license (public domain)",
{ "Waiver.",
"unconditionally waives",
NULL
}
},
{ "Public domain", "Public domain",
+ NULL,
{ NULL, NULL, NULL }
},
{ "Unknown license", "Unknown license",
+ NULL,
{ NULL, NULL, NULL }
},
};
}
return NULL;
}
+
+const char *get_license_oneliner(const tal_t *ctx, enum license license)
+{
+ return tal_fmt(ctx, "/* %s - see LICENSE file for details */",
+ licenses[license].describe);
+}
#ifndef CCANLINT_LICENSES_H
#define CCANLINT_LICENSES_H
#include <stdbool.h>
+#include <ccan/tal/tal.h>
enum license {
LICENSE_LGPLv2_PLUS,
struct license_info {
const char *name;
const char *shortname;
+ const char *describe;
/* Edit distance is expensive, and this works quite well. */
const char *clause[NUM_CLAUSES];
};
struct manifest;
struct doc_section *find_license_tag(const struct manifest *m);
+const char *get_license_oneliner(const tal_t *ctx, enum license license);
+
#endif /* CCANLINT_LICENSES_H */
}
}
+static void add_license_comment(struct manifest *m, struct score *score)
+{
+ struct file_error *e;
+ const char *license_desc = get_license_oneliner(score, m->license);
+ char *files = tal_strdup(score, ""), *q;
+
+ list_for_each(&score->per_file_errors, e, list)
+ tal_append_fmt(&files, " %s\n", e->file->name);
+
+ q = tal_fmt(score, "The following files don't have a comment:\n%s\n"
+ "Should I prepend '%s'?", files, license_desc);
+ if (!ask(q))
+ return;
+
+ list_for_each(&score->per_file_errors, e, list) {
+ char *tmpname;
+ FILE *out;
+ unsigned int i;
+
+ tmpname = temp_file(score, ".licensed", e->file->name);
+ out = fopen(tmpname, "w");
+ if (!out)
+ err(1, "Opening %s", tmpname);
+ if (fprintf(out, "%s\n", license_desc) < 0)
+ err(1, "Writing %s", tmpname);
+
+ for (i = 0; e->file->lines[i]; i++)
+ if (fprintf(out, "%s\n", e->file->lines[i]) < 0)
+ err(1, "Writing %s", tmpname);
+
+ if (fclose(out) != 0)
+ err(1, "Closing %s", tmpname);
+
+ if (!move_file(tmpname, e->file->fullname))
+ err(1, "Moving %s to %s", tmpname, e->file->fullname);
+ }
+}
+
struct ccanlint license_comment = {
.key = "license_comment",
.name = "Source and header files refer to LICENSE",
.check = check_license_comment,
+ .handle = add_license_comment,
.needs = "license_exists"
};
REGISTER_TEST(license_comment);