[med-svn] [Git][med-team/libarb][upstream] 4 commits: New upstream version 6.0.6
Andreas Tille
gitlab at salsa.debian.org
Fri Jun 7 10:00:17 BST 2019
Andreas Tille pushed to branch upstream at Debian Med / libarb
Commits:
b1335d81 by Andreas Tille at 2019-06-07T08:43:55Z
New upstream version 6.0.6
- - - - -
02d9a51e by Andreas Tille at 2019-06-07T08:48:23Z
New upstream version 6.0.6
- - - - -
b588f403 by Andreas Tille at 2019-06-07T08:51:01Z
New upstream version 6.0.6
- - - - -
030a422d by Andreas Tille at 2019-06-07T08:57:46Z
New upstream version 6.0.6
- - - - -
10 changed files:
- + AISC_MKPTPS/Makefile
- + AISC_MKPTPS/mkptypes.cxx
- + AISC_MKPTPS/needs_libs.mkptypes_o
- + SOURCE_TOOLS/Makefile
- + SOURCE_TOOLS/Makefile.commitbuild
- + SOURCE_TOOLS/arb_main.c
- + SOURCE_TOOLS/arb_main.cxx
- + SOURCE_TOOLS/arb_main.h
- + TEMPLATES/arb_early_check.h
- + TEMPLATES/arb_simple_assert.h
Changes:
=====================================
AISC_MKPTPS/Makefile
=====================================
@@ -0,0 +1,51 @@
+# for variables passed from parent makefile see ../SOURCE_TOOLS/parent_make.txt
+
+.SUFFIXES: .o .cxx .depend
+
+OBJECTS = mkptypes.o
+BINARY = aisc_mkpt
+
+LOCAL_DEFINES=-DSIMPLE_ARB_ASSERT
+LOCAL_MAKEDEPENDFLAGS=$(MAKEDEPENDFLAGS) $(LOCAL_DEFINES)
+
+$(MAIN): $(BINARY)
+
+$(BINARY): $(OBJECTS) $(use_ARB_main)
+ $(LINK_EXECUTABLE) $@ $(use_ARB_main) $(OBJECTS) $(EXECLIBS)
+
+.cxx.o:
+ $(A_CXX) $(cflags) $(cxxflags) $(LOCAL_DEFINES) -c $< $(CXX_INCLUDES) $(POST_COMPILE)
+
+clean:
+ rm -f $(OBJECTS) $(BINARY)
+
+#depends:
+# @echo "No depends here"
+
+DEPENDS = $(OBJECTS:.o=.depend)
+depends: $(DEPENDS)
+ @cat $(DEPENDS) | grep -v '^#' >>Makefile
+ @rm $(DEPENDS)
+$(DEPENDS): depend.init
+depend.init:
+ $(MAKEDEPEND) $(LOCAL_MAKEDEPENDFLAGS) 2>/dev/null # remove dependencies
+.cxx.depend:
+ $(MAKEDEPEND) -f- $(LOCAL_MAKEDEPENDFLAGS) $< 2>/dev/null >$@
+
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+# Do not add dependencies manually - use 'make depend' in $ARBHOME
+# For formatting issues see SOURCE_TOOLS/fix_depends.pl (from main)
+
+mkptypes.o: $(ARBHOME)/INCLUDE/arb_assert.h
+mkptypes.o: $(ARBHOME)/INCLUDE/arb_early_check.h
+mkptypes.o: $(ARBHOME)/INCLUDE/arb_simple_assert.h
+mkptypes.o: $(ARBHOME)/INCLUDE/arbtools.h
+mkptypes.o: $(ARBHOME)/INCLUDE/attributes.h
+mkptypes.o: $(ARBHOME)/INCLUDE/cxxforward.h
+mkptypes.o: $(ARBHOME)/INCLUDE/dupstr.h
+mkptypes.o: $(ARBHOME)/INCLUDE/gccver.h
+mkptypes.o: $(ARBHOME)/INCLUDE/static_assert.h
+mkptypes.o: $(ARBHOME)/INCLUDE/test_global.h
+mkptypes.o: $(ARBHOME)/INCLUDE/test_unit.h
=====================================
AISC_MKPTPS/mkptypes.cxx
=====================================
@@ -0,0 +1,1791 @@
+/* Program to extract function declarations from C/C++ source code
+ *
+ * Written by Eric R. Smith and placed in the public domain
+ *
+ * Thanks to:
+ *
+ * Jwahar R. Bammi, for catching several bugs and providing the Unix makefiles
+ * Byron T. Jenings Jr. for cleaning up the space code, providing a Unix
+ * manual page, and some ANSI and C++ improvements.
+ * Skip Gilbrech for code to skip parameter names in prototypes.
+ * ... and many others for helpful comments and suggestions.
+ *
+ * Many extension were made for use in ARB build process
+ * by Ralf Westram <ralf at arb-home.de>
+ */
+
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <unistd.h>
+#include <cstdio>
+#include <cctype>
+#include <cstring>
+#include <cstdarg>
+
+#include <arb_early_check.h>
+#include <attributes.h>
+
+#include <arb_simple_assert.h>
+#include <arbtools.h>
+
+#define mp_assert(cond) arb_assert(cond)
+
+static void Version();
+
+#if defined(DEBUG)
+// #define DEBUG_PRINTS
+#endif // DEBUG
+
+#ifdef DEBUG_PRINTS
+#define DEBUG_PRINT(s) fputs((s), stderr)
+#define DEBUG_PRINT_STRING(name, str) fprintf(stderr, "%s'%s'\n", name, str)
+#else
+#define DEBUG_PRINT(s)
+#define DEBUG_PRINT_STRING(name, str)
+#endif
+
+#define PRINT(s) fputs((s), stdout)
+
+#define IS_CSYM(x) ((x) > 0 && (isalnum(x) || (x) == '_'))
+#define ABORTED ((Word *) -1)
+#define MAXPARAM 20 // max. number of parameters to a function
+#define NEWBUFSIZ (20480*sizeof(char)) // new buffer size
+
+
+static int donum = 0; // print line numbers?
+static int define_macro = 0; // define macro for K&R prototypes?
+static int use_macro = 0; // use a macro to support K&R prototypes?
+static int use_main = 0; // add prototype for main?
+static int no_parm_names = 0; // no parm names - only types
+static int print_extern = 0; // use "extern" before function declarations
+static int dont_promote = 0; // don't promote prototypes
+static int promote_lines = 0; // promote 'AISC_MKPT_PROMOTE'-lines
+static int aisc = 0; // aisc compatible output
+static int cansibycplus = 0; // produce extern "C"
+static int promote_extern_c = 0; // produce extern "C" into prototype
+static int extern_c_seen = 0; // true if extern "C" was parsed
+static int search__ATTR__ = 0; // search for ARB-__attribute__-macros (__ATTR__) ?
+
+static const char *include_wrapper = NULL; // add include wrapper (contains name of header or NULL)
+
+static int inquote = 0; // in a quote??
+static int newline_seen = 1; // are we at the start of a line
+static int glastc = ' '; // last char. seen by getsym()
+
+static char *current_file = 0; // name of current file
+static char *current_dir = 0; // name of current directory
+static const char *header_comment = 0; // comment written into header
+static long linenum = 1L; // line number in current file
+
+static char const *macro_name = "P_"; // macro to use for prototypes
+static char const *ourname; // our name, from argv[] array
+
+// ------------------------------------------------------------
+
+static void errorAt(long line, const char *msg) {
+ printf("\n"
+ "#line %li \"%s/%s\"\n"
+ "#error in aisc_mkpt: %s\n",
+ line,
+ current_dir,
+ current_file,
+ msg);
+}
+
+static void error(const char *msg) {
+ errorAt(linenum, msg);
+}
+
+static void errorf(const char *format, ...) __attribute__((format(__printf__, 1, 2)));
+static void errorf(const char *format, ...) {
+ const int BUFFERSIZE = 1000;
+ char buffer[BUFFERSIZE];
+ va_list args;
+
+ va_start(args, format);
+ int printed = vsprintf(buffer, format, args);
+ if (printed >= BUFFERSIZE) {
+ fputs("buffer overflow\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ va_end(args);
+
+ error(buffer);
+}
+
+// ------------------------------------------------------------
+
+struct SymPart {
+ char *part;
+ int len; // len of part
+ bool atStart; // part has to match at start of name
+
+ SymPart *And;
+ SymPart *next;
+};
+
+static SymPart* makeSymPart(char *token) {
+ SymPart *sp = (SymPart*)malloc(sizeof(*sp));
+
+ sp->atStart = token[0] == '^';
+ char *part = sp->atStart ? token+1 : token;
+ char *plus = strchr(part, '+');
+
+ if (plus) {
+ *plus++ = 0;
+ sp->And = makeSymPart(plus);
+ }
+ else {
+ sp->And = NULL;
+ }
+ sp->part = strdup(part);
+ sp->len = strlen(sp->part);
+
+ sp->next = NULL;
+
+ return sp;
+}
+
+static void addSymParts(SymPart*& symParts, const char *parts) {
+ char *p = strdup(parts);
+ const char *sep = ",";
+ char *s = strtok(p, sep);
+
+ while (s) {
+ SymPart *sp = makeSymPart(s);
+ sp->next = symParts;
+ symParts = sp;
+ s = strtok(0, sep);
+ }
+
+ free(p);
+}
+
+static bool matchesSymPart(const SymPart* symParts, const char *name) {
+ const SymPart *sp = symParts;
+ bool matches = false;
+
+ while (sp && !matches) {
+ if (sp->atStart) {
+ matches = strncmp(name, sp->part, sp->len) == 0;
+ }
+ else {
+ matches = strstr(name, sp->part) != NULL;
+ }
+ if (matches && sp->And) matches = matchesSymPart(sp->And, name);
+ sp = sp->next;
+ }
+
+ return matches;
+}
+
+static void freeSymParts(SymPart*& symParts) {
+ SymPart *next = symParts;
+
+ while (next) {
+ SymPart *del = next;
+ next = del->next;
+
+ if (del->And) freeSymParts(del->And);
+ free(del->part);
+ free(del);
+ }
+
+ symParts = NULL;
+}
+
+// ----------------------------------------
+
+static SymPart *requiredSymParts = 0; // only create prototypes if function-name matches one of these parts
+static SymPart *excludedSymParts = 0; // DONT create prototypes if function-name matches one of these parts
+
+inline void addRequiredSymParts(const char *parts) { addSymParts(requiredSymParts, parts); }
+inline void addExcludedSymParts(const char *parts) { addSymParts(excludedSymParts, parts); }
+
+inline void freeRequiredSymParts() { freeSymParts(requiredSymParts); }
+inline void freeExcludedSymParts() { freeSymParts(excludedSymParts); }
+
+inline bool hasRequiredSymPart(const char *name) { return !requiredSymParts || matchesSymPart(requiredSymParts, name); }
+inline bool hasExcludedSymPart(const char *name) { return excludedSymParts && matchesSymPart(excludedSymParts, name); }
+
+inline bool wantPrototypeFor(const char *name) {
+ return hasRequiredSymPart(name) && !hasExcludedSymPart(name);
+}
+
+// ----------------------------------------
+
+struct Word {
+ Word *next;
+ char string[1];
+};
+
+// Routines for manipulating lists of words.
+
+static Word *word_alloc(const char *s)
+{
+ Word *w;
+
+ /* note that sizeof(Word) already contains space for a terminating null
+ * however, we add 1 so that typefixhack can promote "float" to "double"
+ * by just doing a strcpy.
+ */
+ w = (Word *) malloc(sizeof(Word) + strlen(s) + 1);
+ strcpy(w->string, s);
+ w->next = NULL;
+ return w;
+}
+
+static void word_free(Word *w)
+{
+ Word *oldw;
+ while (w) {
+ oldw = w;
+ w = w->next;
+ free(oldw);
+ }
+}
+
+static int List_len(Word *w) {
+ // return the length of a list
+ // empty words are not counted
+ int count = 0;
+
+ while (w) {
+ if (*w->string) count++;
+ w = w->next;
+ }
+ return count;
+}
+
+static Word *word_append(Word *w1, Word *w2) {
+ // Append two lists, and return the result
+
+ Word *r, *w;
+
+ r = w = word_alloc("");
+
+ while (w1) {
+ w->next = word_alloc(w1->string);
+ w = w->next;
+ w1 = w1->next;
+ }
+ while (w2) {
+ w->next = word_alloc(w2->string);
+ w = w->next;
+ w2 = w2->next;
+ }
+
+ return r;
+}
+
+static int foundin(Word *w1, Word *w2) {
+ // see if the last entry in w2 is in w1
+
+ while (w2->next)
+ w2 = w2->next;
+
+ while (w1) {
+ if (strcmp(w1->string, w2->string)==0)
+ return 1;
+ w1 = w1->next;
+ }
+ return 0;
+}
+
+static void addword(Word *w, const char *s) {
+ // add the string s to the given list of words
+
+ while (w->next) w = w->next;
+ w->next = word_alloc(s);
+
+ DEBUG_PRINT("addword: '");
+ DEBUG_PRINT(s);
+ DEBUG_PRINT("'\n");
+}
+
+static void typefixhack(Word *w) {
+ // typefixhack: promote formal parameters of type "char", "unsigned char",
+ // "short", or "unsigned short" to "int".
+
+ Word *oldw = 0;
+
+ if (dont_promote)
+ return;
+
+ while (w) {
+ if (*w->string) {
+ if ((strcmp(w->string, "char")==0 || strcmp(w->string, "short")==0) && (List_len(w->next) < 2)) {
+ // delete any "unsigned" specifier present -- yes, it's supposed to do this
+ if (oldw && strcmp(oldw->string, "unsigned")==0) {
+ oldw->next = w->next;
+ free(w);
+ w = oldw;
+ }
+ strcpy(w->string, "int");
+ }
+ else if (strcmp(w->string, "float")==0 && List_len(w->next) < 2) {
+ strcpy(w->string, "double");
+ }
+ }
+ w = w->next;
+ }
+}
+
+static int ngetc(FILE *f) {
+ // read a character: if it's a newline, increment the line count
+
+ int c;
+
+ c = getc(f);
+ if (c == '\n') linenum++;
+
+ return c;
+}
+
+#define MAX_COMMENT_SIZE 10000
+
+static char last_comment[MAX_COMMENT_SIZE];
+static int lc_size = 0;
+static char *found__ATTR__ = 0;
+
+static void clear_found_attribute() {
+ free(found__ATTR__);
+ found__ATTR__ = 0;
+}
+
+static const char *nextNonSpace(const char* ptr) {
+ while (isspace(*ptr)) ++ptr;
+ return ptr;
+}
+static const char *nextNonWord(const char* ptr) {
+ while (isalnum(*ptr) || *ptr == '_') ++ptr;
+ return ptr;
+}
+
+inline const char *matchingParen(const char *from) {
+ int open = 1;
+ int i;
+ for (i = 1; from[i] && open>0; ++i) {
+ switch (from[i]) {
+ case '(': open++; break;
+ case ')': open--; break;
+ }
+ }
+ if (open) return NULL; // no matching closing paren
+ return from+i-1;
+}
+
+// -----------------
+// LinePart
+
+class LinePart {
+ const char *line;
+ size_t linelen; // of line
+
+ size_t pos;
+ size_t size;
+
+ bool part_is_legal() { return (pos <= linelen) && ((pos+size) <= linelen); }
+
+ void set(size_t newPos, size_t newSize) {
+ pos = newPos;
+ size = newSize;
+ mp_assert(part_is_legal());
+ }
+
+public:
+
+ LinePart(const char *wholeLine, size_t len = -1U)
+ : line(wholeLine),
+ linelen(len != -1U ? len : strlen(line))
+ {
+ mp_assert(line[linelen] == 0);
+ undefine();
+ }
+
+ size_t get_size() const { return size; }
+ bool is_empty() const { return !size; }
+
+ const char *whole_line() const { return line; }
+
+ void define(const char *start, const char *end) { set(start-line, end-start+1); }
+ void undefine() { set(0, 0); }
+
+ void copyTo(char *buffer) const {
+ mp_assert(!is_empty());
+ memcpy(buffer, line+pos, size);
+ buffer[size] = 0;
+ }
+
+ LinePart behind() const {
+ mp_assert(!is_empty());
+ size_t behind_offset = pos+size;
+ mp_assert(linelen >= behind_offset);
+ return LinePart(line+behind_offset, linelen-behind_offset);
+ }
+
+ void error(const char *format) {
+ // 'format' has to contain one '%s'
+ mp_assert(!is_empty());
+ char part[get_size()+1];
+ copyTo(part);
+ errorf(format, part);
+ undefine();
+ }
+};
+
+
+// ------------------
+// PartQueue
+
+class PartQueue : virtual Noncopyable {
+ LinePart first;
+ PartQueue *next;
+ size_t size;
+
+ bool is_empty() const { return !size; }
+ size_t get_size() const { return size; }
+
+ void copyPartsTo(char *buffer) const {
+ mp_assert(!first.is_empty());
+ first.copyTo(buffer);
+ buffer += first.get_size();
+ if (next) {
+ *buffer++ = ' ';
+ next->copyPartsTo(buffer);
+ }
+ }
+
+public:
+ PartQueue(LinePart first_)
+ : first(first_),
+ next(0),
+ size(first.get_size())
+ {}
+ ~PartQueue() { delete next; }
+
+ void append(PartQueue *mp) {
+ mp_assert(!next);
+ next = mp;
+ size += 1+mp->get_size(); // add pos for space
+ }
+
+ char *to_string() {
+ char *result = (char *)malloc(get_size()+1);
+ copyPartsTo(result);
+ mp_assert(get_size() == strlen(result));
+ return result;
+ }
+};
+
+// ------------------------
+// AttributeParser
+
+class AttributeParser {
+ const char *attrName;
+ size_t attrNameLen;
+ bool expandName; // try to expand 'attrName'
+ bool expectParens; // otherwise parens are optional
+
+public:
+ AttributeParser(const char *attrName_, bool expandName_, bool expectParens_)
+ : attrName(attrName_),
+ attrNameLen(strlen(attrName)),
+ expandName(expandName_),
+ expectParens(expectParens_)
+ {}
+
+private:
+ void parse_one_attr(LinePart& part) const {
+ const char *found = strstr(part.whole_line(), attrName);
+ if (found) {
+ const char *behind = found+attrNameLen;
+ if (expandName) behind = nextNonWord(behind);
+ const char *openParen = nextNonSpace(behind);
+
+ if (*openParen == '(') {
+ const char *closeParen = matchingParen(openParen);
+ if (closeParen) part.define(found, closeParen);
+ else {
+ part.define(found, openParen);
+ part.error("Could not find matching paren after '%s'");
+ }
+ }
+ else {
+ part.define(found, behind-1);
+ if (expectParens) part.error("Expected to see '(' after '%s'");
+ }
+ }
+ }
+
+ // rest is not really part of this class - may go to abstract base class if needed
+
+ PartQueue *parse_all(LinePart from) const {
+ parse_one_attr(from);
+ if (from.is_empty()) return NULL;
+
+ PartQueue *head = new PartQueue(from);
+ PartQueue *rest = parse_all(from.behind());
+ if (rest) head->append(rest);
+
+ return head;
+ }
+
+public:
+ char *parse(const char *toParse, size_t toParseSize) const {
+ char *result = NULL;
+ PartQueue *found_attributes = parse_all(LinePart(toParse, toParseSize));
+
+ if (found_attributes) {
+ result = found_attributes->to_string();
+ delete found_attributes;
+ }
+ return result;
+ }
+};
+
+static void search_comment_for_attribute() {
+ if (!found__ATTR__) { // only parse once (until reset)
+ if (search__ATTR__) {
+ last_comment[lc_size] = 0; // close string
+
+ static AttributeParser ATTR_parser("__ATTR__", true, false);
+ found__ATTR__ = ATTR_parser.parse(last_comment, lc_size);
+ }
+ }
+}
+
+struct promotion {
+ char *to_promote; // text to promote to header
+ promotion *next;
+};
+
+static promotion *promotions = 0;
+
+static void add_promotion(char *to_promote) {
+ promotion *new_promotion = (promotion*)malloc(sizeof(promotion));
+ new_promotion->to_promote = to_promote;
+ new_promotion->next = 0;
+
+ if (!promotions) {
+ promotions = new_promotion;
+ }
+ else { // append
+ promotion *last = promotions;
+ while (last->next) last = last->next;
+
+ last->next = new_promotion;
+ }
+}
+
+static void print_promotions() {
+ promotion *p = promotions;
+
+ if (promotions) fputc('\n', stdout);
+
+ while (p) {
+ promotion *next = p->next;
+
+ printf("%s\n", p->to_promote);
+ free(p->to_promote);
+ free(p);
+
+ p = next;
+ }
+
+ if (promotions) fputc('\n', stdout);
+ promotions = 0;
+}
+
+static const char *promotion_tag = "AISC_MKPT_PROMOTE:";
+static int promotion_tag_len = 18;
+
+static void search_comment_for_promotion() {
+ char *promotion_found;
+ last_comment[lc_size] = 0; // close string
+
+ promotion_found = strstr(last_comment, promotion_tag);
+ while (promotion_found) {
+ char *behind_promo = promotion_found+promotion_tag_len;
+ char *eol, *eoc;
+ mp_assert(behind_promo[-1] == ':'); // wrong promotion_tag_len
+
+ eol = strchr(behind_promo, '\n');
+ eoc = strstr(behind_promo, "*/");
+
+ if (eoc && eol) {
+ if (eoc<eol) eol = eoc;
+ }
+ else if (!eol) {
+ eol = eoc;
+ }
+
+ if (!eol) eol = strchr(behind_promo, 0);
+
+ if (eol) {
+ while (eol>behind_promo && eol[-1] == ' ') --eol; // trim spaces at eol
+ }
+
+ mp_assert(eol);
+ if (!eol) {
+ promotion_found = 0;
+ }
+ else {
+ int promo_length = eol-behind_promo;
+ char *to_promote = (char*)malloc(promo_length+1);
+
+ memcpy(to_promote, behind_promo, promo_length);
+ to_promote[promo_length] = 0;
+
+ DEBUG_PRINT("promotion found!\n");
+
+ add_promotion(to_promote);
+ promotion_found = strstr(eol, promotion_tag);
+ }
+ }
+}
+
+/* read the next character from the file. If the character is '\' then
+ * read and skip the next character. Any comment sequence is converted
+ * to a blank.
+ *
+ * if a comment contains __ATTR__ and search__ATTR__ != 0
+ * the attribute string is stored in found__ATTR__
+ */
+
+
+static int fnextch(FILE *f) {
+ int c, lastc, incomment;
+
+ c = ngetc(f);
+ while (c == '\\') {
+ DEBUG_PRINT("fnextch: in backslash loop\n");
+ ngetc(f); // skip a character
+ c = ngetc(f);
+ }
+ if (c == '/' && !inquote) {
+ c = ngetc(f);
+ if (c == '*') {
+ long commentStartLine = linenum;
+
+ incomment = 1;
+ c = ' ';
+ DEBUG_PRINT("fnextch: comment seen\n");
+ lc_size = 0;
+
+ while (incomment) {
+ lastc = c;
+ c = ngetc(f);
+ last_comment[lc_size++] = c;
+ mp_assert(lc_size<MAX_COMMENT_SIZE);
+
+ if (lastc == '*' && c == '/') incomment = 0;
+ else if (c < 0) {
+ error("EOF reached in comment");
+ errorAt(commentStartLine, "comment started here");
+ return c;
+ }
+ }
+ if (search__ATTR__) search_comment_for_attribute();
+ if (promote_lines) search_comment_for_promotion();
+ return fnextch(f);
+ }
+ else if (c == '/') { // C++ style comment
+ incomment = 1;
+ c = ' ';
+ DEBUG_PRINT("fnextch: C++ comment seen\n");
+ lc_size = 0;
+
+ while (incomment) {
+ lastc = c;
+ c = ngetc(f);
+ last_comment[lc_size++] = c;
+ mp_assert(lc_size<MAX_COMMENT_SIZE);
+
+ if (lastc != '\\' && c == '\n') incomment = 0;
+ else if (c < 0) break;
+ }
+ if (search__ATTR__) search_comment_for_attribute();
+ if (promote_lines) search_comment_for_promotion();
+
+ if (c == '\n') return c;
+ return fnextch(f);
+ }
+ else {
+ // if we pre-fetched a linefeed, remember to adjust the line number
+ if (c == '\n') linenum--;
+ ungetc(c, f);
+ return '/';
+ }
+ }
+ return c;
+}
+
+
+static int nextch(FILE *f) {
+ // Get the next "interesting" character. Comments are skipped, and strings
+ // are converted to "0". Also, if a line starts with "#" it is skipped.
+
+ int c = fnextch(f);
+
+ // skip preprocessor directives
+ // EXCEPTION: #line nnn or #nnn lines are interpreted
+
+ if (newline_seen && c == '#') {
+ // skip blanks
+ do {
+ c = fnextch(f);
+ } while (c >= 0 && (c == '\t' || c == ' '));
+
+ // check for #line
+ if (c == 'l') {
+ c = fnextch(f);
+ if (c != 'i') // not a #line directive
+ goto skip_rest_of_line;
+ do {
+ c = fnextch(f);
+ } while (c >= 0 && c != '\n' && !isdigit(c));
+ }
+
+ // if we have a digit it's a line number, from the preprocessor
+ if (c >= 0 && isdigit(c)) {
+ char numbuf[10];
+ char *p = numbuf;
+ for (int n = 8; n >= 0; --n) {
+ *p++ = c;
+ c = fnextch(f);
+ if (c <= 0 || !isdigit(c))
+ break;
+ }
+ *p = 0;
+ linenum = atol(numbuf) - 1;
+ }
+
+ // skip the rest of the line
+ skip_rest_of_line :
+ while (c >= 0 && c != '\n')
+ c = fnextch(f);
+ if (c < 0)
+ return c;
+ }
+ newline_seen = (c == '\n');
+
+ if (c == '\'' || c == '\"') {
+ char buffer[11];
+ int index = 0;
+ long quoteStartLine = linenum;
+
+ DEBUG_PRINT("nextch: in a quote\n");
+ inquote = c;
+ while ((c = fnextch(f)) >= 0) {
+ if (c == inquote) {
+ buffer[index] = 0;
+ DEBUG_PRINT("quoted content='");
+ DEBUG_PRINT(buffer);
+ DEBUG_PRINT("'\n");
+
+ DEBUG_PRINT("nextch: out of quote\n");
+
+ if (linenum != quoteStartLine) {
+ error("multiline quotes");
+ errorAt(quoteStartLine, "quotes opened here");
+ }
+
+ if (inquote=='\"' && strcmp(buffer, "C")==0) {
+ inquote = 0;
+ return '$'; // found "C" (needed for 'extern "C"')
+ }
+ inquote = 0;
+ return '0';
+ }
+ else {
+ if (index<10) buffer[index++] = c;
+ }
+ }
+ error("EOF in a quote");
+ errorAt(quoteStartLine, "quote started here");
+ DEBUG_PRINT("nextch: EOF in a quote\n");
+ }
+ return c;
+}
+
+static int getsym(char *buf, FILE *f) {
+ /* Get the next symbol from the file, skipping blanks.
+ * Return 0 if OK, -1 for EOF.
+ * Also collapses everything between { and }
+ */
+
+ int c;
+ int inbrack = 0;
+
+#if defined(DEBUG_PRINTS)
+ char *bufStart = buf;
+#endif // DEBUG_PRINTS
+
+ c = glastc;
+ while ((c > 0) && isspace(c)) {
+ c = nextch(f);
+ }
+
+ if (c < 0) {
+ DEBUG_PRINT("EOF read in getsym\n");
+ return -1;
+ }
+
+ if (c == '{') {
+ long bracketStartLine = linenum;
+
+ inbrack = 1;
+ DEBUG_PRINT("getsym: in '{'\n");
+ while (inbrack) {
+ c = nextch(f);
+ if (c < 0) {
+ error("EOF seen in bracket loop (unbalanced brackets?)");
+ errorAt(bracketStartLine, "bracket opened here");
+ DEBUG_PRINT("getsym: EOF seen in bracket loop\n");
+ glastc = c;
+ return c;
+ }
+ if (c == '{') {
+ inbrack++;
+#if defined(DEBUG_PRINTS)
+ fprintf(stderr, "inbrack=%i (line=%li)\n", inbrack, linenum);
+#endif // DEBUG_PRINTS
+ }
+ else if (c == '}') {
+ inbrack--;
+#if defined(DEBUG_PRINTS)
+ fprintf(stderr, "inbrack=%i (line=%li)\n", inbrack, linenum);
+#endif // DEBUG_PRINTS
+ }
+ }
+ strcpy(buf, "{}");
+ glastc = nextch(f);
+ DEBUG_PRINT("getsym: returning brackets '");
+ }
+ else if (!IS_CSYM(c)) {
+ *buf++ = c;
+ *buf = 0;
+ glastc = nextch(f);
+
+ DEBUG_PRINT("getsym: returning special symbol '");
+ }
+ else {
+ while (IS_CSYM(c)) {
+ *buf++ = c;
+ c = nextch(f);
+ }
+ *buf = 0;
+ glastc = c;
+ DEBUG_PRINT("getsym: returning word '");
+ }
+
+ DEBUG_PRINT(bufStart);
+ DEBUG_PRINT("'\n");
+
+ return 0;
+}
+
+static int skipit(char *buf, FILE *f) {
+ // skip until a ";" or the end of a function declaration is seen
+
+ int i;
+ do {
+ DEBUG_PRINT("in skipit loop\n");
+
+ i = getsym(buf, f);
+ if (i < 0) return i;
+
+ DEBUG_PRINT("skipit: '");
+ DEBUG_PRINT(buf);
+ DEBUG_PRINT("'\n");
+
+ } while (*buf != ';' && *buf != '{');
+
+ return 0;
+}
+
+static int is_type_word(char *s) {
+ // find most common type specifiers for purpose of ruling them out as parm names
+
+ static const char *typewords[] = {
+ "char", "const", "double", "enum",
+ "float", "int", "long", "short",
+ "signed", "struct", "union", "unsigned",
+ "void", "volatile", (char *)0
+ };
+
+ const char **ss;
+
+ for (ss = typewords; *ss; ++ss)
+ if (strcmp(s, *ss) == 0)
+ return 1;
+
+ return 0;
+}
+
+
+/* Ad-hoc macro to recognize parameter name for purposes of removal.
+ * Idea is to remove the bulk of easily recognized parm names without
+ * losing too many type specifiers. (sg)
+ */
+#define IS_PARM_NAME(w) \
+ (IS_CSYM(*(w)->string) && !is_type_word((w)->string) && \
+ (!(w)->next || *(w)->next->string == ',' || \
+ *(w)->next->string == '['))
+
+
+static Word *typelist(Word *p) {
+ // given a list representing a type and a variable name, extract just
+ // the base type, e.g. "struct word *x" would yield "struct word"
+
+ Word *w, *r;
+
+ r = w = word_alloc("");
+ while (p && p->next) {
+ // handle int *x --> int
+ if (p->string[0] && !IS_CSYM(p->string[0]))
+ break;
+ // handle int x[] --> int
+ if (p->next->string[0] == '[')
+ break;
+ w->next = word_alloc(p->string);
+ w = w->next;
+ p = p->next;
+ }
+ return r;
+}
+
+static Word *getparamlist(FILE *f) {
+ // Get a parameter list; when this is called the next symbol in line
+ // should be the first thing in the list.
+
+ static Word *pname[MAXPARAM]; // parameter names
+ Word *tlist; // type name
+ Word *plist; // temporary
+ int np = 0; // number of parameters
+ int typed[MAXPARAM]; // parameter has been given a type
+ int tlistdone; // finished finding the type name
+ int sawsomething;
+ int i;
+ int inparen = 0;
+ char buf[80];
+
+ DEBUG_PRINT("in getparamlist\n");
+ for (i = 0; i < MAXPARAM; i++)
+ typed[i] = 0;
+
+ plist = word_alloc("");
+
+ // first, get the stuff inside brackets (if anything)
+
+ sawsomething = 0; // gets set nonzero when we see an arg
+ for (;;) {
+ if (getsym(buf, f) < 0) return NULL;
+ if (*buf == ')' && (--inparen < 0)) {
+ if (sawsomething) { // if we've seen an arg
+ pname[np] = plist;
+ plist = word_alloc(""); // @@@ Value stored to 'plist' is never read
+ np++;
+ }
+ break;
+ }
+ if (*buf == ';') { // something weird
+ return ABORTED;
+ }
+ sawsomething = 1; // there's something in the arg. list
+ if (*buf == ',' && inparen == 0) {
+ pname[np] = plist;
+ plist = word_alloc("");
+ np++;
+ }
+ else {
+ addword(plist, buf);
+ if (*buf == '(') inparen++;
+ }
+ }
+
+ // next, get the declarations after the function header
+
+ inparen = 0;
+
+ tlist = word_alloc("");
+ plist = word_alloc("");
+ tlistdone = 0;
+ sawsomething = 0;
+ for (;;) {
+ if (getsym(buf, f) < 0) return NULL;
+
+ if (*buf == ',' && !inparen) { // handle a list like "int x,y,z"
+ if (!sawsomething)
+ return NULL;
+ for (i = 0; i < np; i++) {
+ if (!typed[i] && foundin(plist, pname[i])) {
+ typed[i] = 1;
+ word_free(pname[i]);
+ pname[i] = word_append(tlist, plist);
+ // promote types
+ typefixhack(pname[i]);
+ break;
+ }
+ }
+ if (!tlistdone) {
+ tlist = typelist(plist);
+ tlistdone = 1;
+ }
+ word_free(plist);
+ plist = word_alloc("");
+ }
+ else if (*buf == ';') { // handle the end of a list
+ if (!sawsomething)
+ return ABORTED;
+ for (i = 0; i < np; i++) {
+ if (!typed[i] && foundin(plist, pname[i])) {
+ typed[i] = 1;
+ word_free(pname[i]);
+ pname[i] = word_append(tlist, plist);
+ typefixhack(pname[i]);
+ break;
+ }
+ }
+ tlistdone = 0;
+ word_free(tlist); word_free(plist);
+ tlist = word_alloc("");
+ plist = word_alloc("");
+ }
+ else if (strcmp(buf, "{}") == 0) break; // handle the beginning of the function
+ else if (strcmp(buf, "register")) { // otherwise, throw the word into the list (except for "register")
+ addword(plist, buf);
+ if (*buf == '(') inparen++;
+ else if (*buf == ')') inparen--;
+ else sawsomething = 1;
+ }
+ }
+
+ // Now take the info we have and build a prototype list
+
+ // empty parameter list means "void"
+ if (np == 0) return word_alloc("void");
+
+ plist = tlist = word_alloc("");
+
+ /* how to handle parameters which contain only one word ?
+ *
+ * void -> void
+ * UNFIXED -> UNFIXED see ../SL/CB/cb_base.h at UNFIXED
+ * xxx -> int xxx (if AUTO_INT is defined)
+ * int -> int dummyXX (otherwise)
+ */
+
+ // #define AUTO_INT
+
+ {
+#if !defined(AUTO_INT)
+ int dummy_counter = 1;
+ char dummy_name[] = "dummy_xx";
+#define DUMMY_COUNTER_POS 6
+#endif
+
+ for (i = 0; i < np; i++) {
+#if !defined(AUTO_INT)
+ int add_dummy_name = 0;
+#endif
+ {
+ Word *pn_list = pname[i];
+ int cnt = 0;
+ bool is_void = false;
+ bool is_UNFIXED = false;
+
+ while (pn_list) { // count words
+ if (pn_list->string[0]) {
+ ++cnt;
+ if (strcmp(pn_list->string, "void")==0) is_void = true;
+ if (strcmp(pn_list->string, "UNFIXED")==0) is_UNFIXED = true;
+ }
+ pn_list = pn_list->next;
+ }
+ if (cnt==1 && !is_void && !is_UNFIXED) { // only name, but neighter 'void' nor 'UNFIXED'
+ // no type or no parameter name
+#ifdef AUTO_INT
+ // If no type provided, make it an "int"
+ addword(tlist, "int"); // add int to tlist before adding pname[i]
+#else
+ add_dummy_name = 1; // add a dummy name after adding pname[i]
+#endif
+ }
+ }
+
+ while (tlist->next) tlist = tlist->next;
+ tlist->next = pname[i];
+
+#if !defined(AUTO_INT)
+ if (add_dummy_name) {
+ mp_assert(dummy_counter<100);
+ dummy_name[DUMMY_COUNTER_POS] = (dummy_counter/10)+'0';
+ dummy_name[DUMMY_COUNTER_POS] = (dummy_counter%10)+'0';
+ addword(tlist, dummy_name);
+ dummy_counter++;
+ }
+#endif
+
+ if (i < np - 1) addword(tlist, ",");
+ }
+ }
+
+ return plist;
+}
+
+inline Word *getLastPtrRef(Word *w) {
+ Word *last = NULL;
+ while (w) {
+ if (strchr("&*", w->string[0]) == NULL) break;
+ last = w;
+ w = w->next;
+ }
+ return last;
+}
+
+static void emit(Word *wlist, Word *plist, long startline) {
+ // emit a function declaration. The attributes and name of the function
+ // are in wlist; the parameters are in plist.
+
+ Word *w;
+ int count = 0;
+ int isstatic = 0;
+ int ismain = 0;
+ int refs = 0;
+
+ if (promote_lines) print_promotions();
+
+ for (w = wlist; w; w = w->next) {
+ if (w->string[0]) {
+ count ++;
+ if (strcmp(w->string, "static") == 0) isstatic = 1;
+ else if (strcmp(w->string, "main") == 0) ismain = 1;
+ }
+ }
+
+ if (ismain && !use_main) return;
+
+ if (aisc) {
+ if (count < 2) {
+ printf("int\t");
+ w = wlist;
+ }
+ else {
+ refs = 0;
+ for (w = wlist; w; w = w->next) {
+ if (w->string[0]) {
+ printf("%s,\t", w->string);
+ w = w->next;
+ break;
+ }
+ }
+ }
+ for (; w; w = w->next) {
+ if (w->string[0] == '*') {
+ refs++;
+ continue;
+ }
+ if (w->string[0]) {
+ printf("%s,", w->string);
+ break;
+ }
+ }
+ if (refs) {
+ printf("\tlink%i", refs);
+ refs = 0;
+ }
+ else {
+ printf("\tterm");
+ }
+
+ if (strcmp(plist->string, "void") != 0) { // if parameter is not 'void'
+ printf(",\t{\n");
+ printf("\t at TYPE,\t at IDENT,\t at REF;\n");
+
+ int name_seen = 0;
+ int unnamed_counter = 1;
+ for (w = plist; w; w = w->next) {
+ if (w->string[0] == '*') {
+ refs++;
+ name_seen = 0;
+ continue;
+ }
+ if (w->string[0] == ',') {
+ if (refs) {
+ printf("\tlink%i;\n", refs);
+ refs = 0;
+ continue;
+ }
+ else {
+ printf("\tterm;\n");
+ continue;
+ }
+ }
+ if (w->string[0]) {
+ printf("\t%s,", w->string);
+ name_seen = 1;
+ }
+ }
+ if (refs) {
+ if (!name_seen) { // automatically insert missing parameter names
+ printf("\tunnamed%i,", unnamed_counter++);
+ }
+ printf("\tlink%i;\n", refs);
+ refs = 0;
+ }
+ else {
+ printf("\tterm;\n");
+ }
+ printf("}");
+ }
+ printf(";\n\n");
+ return;
+ }
+ DEBUG_PRINT("emit called\n");
+ if (donum)
+ printf("/*%8ld */ ", startline);
+
+
+ // if the -e flag was given, and it's not a static function, print "extern"
+
+ if (print_extern && !isstatic) {
+ printf("extern ");
+ }
+
+ int spaceBeforeNext = 0;
+ if (count < 2) {
+ printf("int");
+ spaceBeforeNext = 1;
+ }
+
+ for (w = wlist; w; w = w->next) {
+ if (spaceBeforeNext) {
+ DEBUG_PRINT("emit[1] ' '\n");
+ putchar(' ');
+ }
+ printf("%s", w->string);
+ DEBUG_PRINT_STRING("emit[2] ", w->string);
+ spaceBeforeNext = IS_CSYM(w->string[0]);
+ }
+
+ if (use_macro) printf(" %s((", macro_name);
+ else putchar('(');
+ DEBUG_PRINT("emit[3] '('\n");
+
+ spaceBeforeNext = 0;
+ for (w = plist; w; w = w->next) {
+ if (no_parm_names && IS_PARM_NAME(w)) continue;
+
+ const char *token = w->string;
+ char tokStart = token[0];
+
+ if (!tokStart) continue; // empty token
+
+ if (tokStart == ',') spaceBeforeNext = 1;
+ else if (strchr("[])", tokStart) != NULL) spaceBeforeNext = 0;
+ else {
+ int nextSpaceBeforeNext;
+ if (strchr("&*", tokStart) != NULL) {
+ if (spaceBeforeNext) {
+ Word *lastPtrRef = getLastPtrRef(w);
+ if (lastPtrRef->string[0] == '&') spaceBeforeNext = 0;
+ }
+ nextSpaceBeforeNext = tokStart == '&';
+ }
+ else {
+ nextSpaceBeforeNext = IS_CSYM(tokStart);;
+ }
+ if (spaceBeforeNext) {
+ putchar(' ');
+ DEBUG_PRINT("emit[4] ' '\n");
+ }
+ spaceBeforeNext = nextSpaceBeforeNext;
+ }
+ fputs(token, stdout);
+ DEBUG_PRINT_STRING("emit[5] ", token);
+ }
+
+ if (use_macro) PRINT("))");
+ else PRINT(")");
+ DEBUG_PRINT("emit[6] ')'\n");
+
+ if (found__ATTR__) { PRINT(" "); PRINT(found__ATTR__); }
+
+ PRINT(";\n");
+}
+
+static void getdecl(FILE *f, const char *header) {
+ // parse all function declarations and print to STDOUT
+
+ Word *plist, *wlist = NULL;
+ char buf[80];
+ int sawsomething;
+ long startline; // line where declaration started
+ int oktoprint;
+ int header_printed = 0;
+
+ current_file = strdup(header);
+
+ again :
+ DEBUG_PRINT("again\n");
+ word_free(wlist);
+ wlist = word_alloc("");
+ sawsomething = 0;
+ oktoprint = 1;
+ extern_c_seen = 0;
+
+ for (;;) {
+ DEBUG_PRINT("main getdecl loop\n");
+ if (getsym(buf, f) < 0) {
+ DEBUG_PRINT("EOF in getdecl loop\n");
+ return;
+ }
+
+ DEBUG_PRINT("getdecl: '");
+ DEBUG_PRINT(buf);
+ DEBUG_PRINT("'\n");
+
+ // try to guess when a declaration is not an external function definition
+ if (strcmp(buf, ",")==0 ||
+ strcmp(buf, "=")==0 ||
+ strcmp(buf, "typedef")==0 ||
+ strcmp(buf, "[")==0)
+ {
+ skipit(buf, f);
+ goto again;
+ }
+
+ if (strcmp(buf, "{}")==0) {
+ if (!extern_c_seen) skipit(buf, f);
+ goto again;
+ }
+
+ if (strcmp(buf, "extern")==0) {
+ if (getsym(buf, f)<0) {
+ DEBUG_PRINT("EOF in getdecl loop\n");
+ return;
+ }
+
+ DEBUG_PRINT("test auf extern \"C\": '");
+ DEBUG_PRINT(buf);
+ DEBUG_PRINT("'\n");
+
+ if (strcmp(buf, "$") == 0) { // symbol used if "C" was found
+ extern_c_seen = 1;
+ if (promote_extern_c) {
+ addword(wlist, "extern");
+ addword(wlist, "\"C\" ");
+ sawsomething = 1;
+ }
+ continue;
+ }
+
+ skipit(buf, f);
+ goto again;
+ }
+
+ if (strncmp(buf, "__ATTR__", 8) == 0) { // prefix attribute (should only be used for static and inline)
+ DEBUG_PRINT("seen prefix __ATTR__: '");
+ DEBUG_PRINT(buf);
+ DEBUG_PRINT("'\n");
+
+ bool seen_static_or_inline = false;
+
+ while (!seen_static_or_inline) {
+ if (getsym(buf, f)<0) {
+ DEBUG_PRINT("EOF in getdecl loop (behind prefix __ATTR__)\n");
+ return;
+ }
+ if (strcmp(buf, "static") == 0 || strcmp(buf, "inline") == 0) {
+ seen_static_or_inline = true;
+ }
+ else {
+ DEBUG_PRINT("read over (behind prefix __ATTR__): '");
+ DEBUG_PRINT(buf);
+ DEBUG_PRINT("'\n");
+ }
+ }
+ }
+
+ if (oktoprint) {
+ if (strcmp(buf, "static") == 0 || strcmp(buf, "inline") == 0) {
+ oktoprint = 0;
+ }
+ }
+
+
+ if (strcmp(buf, ";") == 0) goto again;
+
+ // A left parenthesis *might* indicate a function definition
+ if (strcmp(buf, "(")==0) {
+ startline = linenum;
+ if (!sawsomething || !(plist = getparamlist(f))) {
+ skipit(buf, f);
+ goto again;
+ }
+ if (plist == ABORTED)
+ goto again;
+
+ // It seems to have been what we wanted
+
+ if (oktoprint) { // check function-name
+ Word *w;
+
+ for (w=wlist; w->next && oktoprint; w=w->next) {
+ if (w->string[0]==':' && w->string[1]==0) oktoprint = 0; // do not emit prototypes for member functions
+ }
+
+ if (oktoprint && !wantPrototypeFor(w->string)) {
+ oktoprint = 0; // => do not emit prototype
+ }
+ }
+
+ if (oktoprint) {
+ if (!header_printed) {
+ if (aisc) printf("\n# %s\n", header);
+ else printf("\n/* %s */\n", header);
+ header_printed = 1;
+ }
+ emit(wlist, plist, startline);
+ }
+ clear_found_attribute();
+
+ word_free(plist);
+ goto again;
+ }
+
+ addword(wlist, buf);
+ sawsomething = 1;
+ }
+}
+
+__ATTR__NORETURN static void Usage(const char *msg = NULL) {
+ fprintf(stderr,
+ "\naisc_mkpts - ARB prototype generator"
+ "\nUsage: %s [options] [files ...]", ourname);
+ fputs("\nSupported options:"
+ "\n -F part[,part]* only promote declarations for functionnames containing one of the parts"
+ "\n if 'part' starts with a '^' functionname has to start with rest of part"
+ "\n -S (like -F) do NOT promote matching declarations (defaults to -S '^TEST_,^NOTEST_')"
+ "\n"
+ "\n Instead of ',' (=or) you may use '+' (=and)"
+ "\n"
+ "\n -G search for ARB macro __ATTR__ in comment behind function header"
+ "\n -P promote /*AISC_MKPT_PROMOTE:forHeader*/ to header"
+ "\n"
+ "\n -w gen.h add standard include wrapper (needs name of generated header)"
+ "\n -c \"text\" add text as comment into header"
+ "\n"
+ "\n -C insert 'extern \"C\"'"
+ "\n -E prefix 'extern \"C\"' at prototype"
+ "\n"
+ "\n -W don't promote types in old style declarations"
+ "\n -x omit parameter names in prototypes"
+ "\n"
+ "\n -K use K&R prototype macro (default assumes header files are strict ANSI)"
+ "\n -D define K&R prototype macro"
+ "\n -p sym use \"sym\" as the prototype macro (default \"P_\")"
+ "\n"
+ "\n -m promote declaration of 'main()' (default is to skip it)"
+ "\n -a make a function list for aisc_includes (default: generate C prototypes)"
+ "\n -e put an explicit \"extern\" keyword in declarations"
+ "\n -n put line numbers of declarations as comments"
+ "\n"
+ "\n -V print version number"
+ "\n -h print this help"
+ "\n"
+ , stderr);
+ if (msg) fprintf(stderr, "\nError: %s", msg);
+ fputc('\n', stderr);
+ exit(EXIT_FAILURE);
+}
+
+static int string_comparator(const void *v0, const void *v1) {
+ return strcmp(*(const char **)v0, *(const char **)v1);
+}
+
+static void MissingArgumentFor(char option) {
+ char buffer[100];
+ sprintf(buffer, "option -%c expects an argument", option);
+ Usage(buffer);
+}
+static void UnknownOption(char option) {
+ char buffer[100];
+ sprintf(buffer, "unknown option -%c", option);
+ Usage(buffer);
+}
+
+int ARB_main(int argc, char *argv[]) {
+ bool exit_if_noargs = false;
+
+ if (argv[0] && argv[0][0]) {
+ ourname = strrchr(argv[0], '/');
+ if (!ourname) ourname = argv[0];
+ }
+ else ourname = "mkptypes";
+
+ argv++; argc--;
+
+ addExcludedSymParts("^TEST_,^NOTEST_"); // exclude unit tests
+
+ char *iobuf = (char *)malloc(NEWBUFSIZ);
+ while (*argv && **argv == '-') {
+ const char *t = *argv++; --argc; t++;
+ while (*t) {
+ if (*t == 'e') print_extern = 1;
+ else if (*t == 'C') cansibycplus = 1;
+ else if (*t == 'E') promote_extern_c = 1;
+ else if (*t == 'W') dont_promote = 1;
+ else if (*t == 'a') aisc = 1;
+ else if (*t == 'G') search__ATTR__ = 1;
+ else if (*t == 'n') donum = 1;
+ else if (*t == 'x') no_parm_names = 1; // no parm names, only types (sg)
+ else if (*t == 'D') define_macro = 1;
+ else if (*t == 'K') use_macro = 1;
+ else if (*t == 'P') promote_lines = 1;
+ else if (*t == 'm') use_main = 1;
+ else if (*t == 'p') {
+ t = *argv++; --argc;
+ if (!t) MissingArgumentFor(*t);
+ use_macro = 1;
+ macro_name = t;
+ break;
+ }
+ else if (*t == 'c') {
+ t = *argv++; --argc;
+ if (!t) MissingArgumentFor(*t);
+ header_comment = t;
+ break;
+ }
+ else if (*t == 'w') {
+ t = *argv++; --argc;
+ if (!t) MissingArgumentFor(*t);
+ include_wrapper = t;
+ break;
+ }
+ else if (*t == 'F') {
+ t = *argv++; --argc;
+ if (!t) MissingArgumentFor(*t);
+ addRequiredSymParts(t);
+ break;
+ }
+ else if (*t == 'S') {
+ t = *argv++; --argc;
+ if (!t) MissingArgumentFor(*t);
+ freeExcludedSymParts();
+ addExcludedSymParts(t);
+ break;
+ }
+ else if (*t == 'V') {
+ exit_if_noargs = true;
+ Version();
+ }
+ else if (*t == 'h') Usage();
+ else UnknownOption(*t);
+ t++;
+ }
+ }
+
+ if (argc == 0 && exit_if_noargs) {
+ exit(EXIT_FAILURE);
+ }
+
+ char *include_macro = 0;
+ if (aisc) {
+ if (header_comment) {
+ printf("# %s\n#\n", header_comment);
+ }
+ fputs("# This file is generated by aisc_mkpt.\n"
+ "# Any changes you make here will be overwritten later!\n"
+ "\n"
+ "@FUNCTION_TYPE, @FUNCTION, @FUNCTION_REF;", stdout);
+ }
+ else {
+ fputs("/*", stdout);
+ if (header_comment) printf(" %s.\n *\n *", header_comment);
+ fputs(" This file is generated by aisc_mkpt.\n"
+ " * Any changes you make here will be overwritten later!\n"
+ " */\n"
+ "\n"
+ , stdout);
+
+ if (include_wrapper) {
+ int p;
+ include_macro = strdup(include_wrapper);
+ for (p = 0; include_macro[p]; p++) {
+ char c = include_macro[p];
+ c = strchr(".-", c) ? '_' : toupper(c);
+ include_macro[p] = c;
+ }
+
+ printf("#ifndef %s\n"
+ "#define %s\n"
+ "\n",
+ include_macro,
+ include_macro);
+ }
+
+ if (use_macro) {
+ if (define_macro) {
+ fprintf(stdout,
+ "#ifndef %s\n"
+ "# if defined(__STDC__) || defined(__cplusplus)\n"
+ "# define %s(s) s\n"
+ "# else\n"
+ "# define %s(s) ()\n"
+ "# endif\n"
+ "#else\n"
+ "# error %s already defined elsewhere\n"
+ "#endif\n\n",
+ macro_name, macro_name, macro_name, macro_name);
+ }
+ else {
+ fprintf(stdout,
+ "#ifndef %s\n"
+ "# error %s is not defined\n"
+ "#endif\n\n",
+ macro_name, macro_name);
+ }
+ }
+ if (search__ATTR__) {
+ fputs("/* define ARB attributes: */\n"
+ "#ifndef ATTRIBUTES_H\n"
+ "# include <attributes.h>\n"
+ "#endif\n\n", stdout);
+ }
+ if (cansibycplus) {
+ fputs("#ifdef __cplusplus\n"
+ "extern \"C\" {\n"
+ "#endif\n\n", stdout);
+ }
+ }
+
+ current_dir = strdup(getcwd(0, 255));
+ if (argc == 0) {
+ getdecl(stdin, "<from stdin>");
+ }
+ else {
+ const char *filename[1000];
+ int fcount = 0;
+
+ while (argc > 0 && *argv) {
+ filename[fcount++] = *argv;
+ argc--; argv++;
+ }
+
+ qsort(&filename, fcount, sizeof(filename[0]), string_comparator);
+
+ for (int i = 0; i<fcount; ++i) {
+ DEBUG_PRINT("trying new file '");
+ DEBUG_PRINT(filename[i]);
+ DEBUG_PRINT("'\n");
+
+ FILE *f = fopen(filename[i], "r");
+ if (!f) {
+ perror(filename[i]);
+ exit(EXIT_FAILURE);
+ }
+ if (iobuf) setvbuf(f, iobuf, _IOFBF, NEWBUFSIZ);
+
+ linenum = 1;
+ newline_seen = 1;
+ glastc = ' ';
+ getdecl(f, filename[i]);
+ fclose(f);
+
+ free(current_file);
+ current_file = 0;
+ }
+ }
+ if (aisc) {
+ }
+ else {
+ if (cansibycplus) {
+ fputs("\n#ifdef __cplusplus\n"
+ "}\n"
+ "#endif\n", stdout);
+ }
+ if (use_macro && define_macro) {
+ printf("\n#undef %s\n", macro_name); // clean up namespace
+ }
+
+ if (include_wrapper) {
+ printf("\n"
+ "#else\n"
+ "#error %s included twice\n"
+ "#endif /* %s */\n",
+ include_wrapper,
+ include_macro);
+ }
+ }
+
+ free(include_macro);
+
+ freeRequiredSymParts();
+ freeExcludedSymParts();
+
+ free(current_file);
+ free(current_dir);
+
+ free(iobuf);
+
+ return EXIT_SUCCESS;
+}
+
+static void Version() {
+ fprintf(stderr, "%s 1.1 ARB\n", ourname);
+}
+
+// --------------------------------------------------------------------------------
+
+#ifdef UNIT_TESTS
+
+#include <test_unit.h>
+
+inline const char *test_extract(bool ATTR, const char *str) {
+ search__ATTR__ = true;
+
+ clear_found_attribute();
+
+ strcpy(last_comment, str);
+ lc_size = strlen(last_comment);
+
+ search_comment_for_attribute();
+
+ return found__ATTR__;
+}
+
+#define TEST_ATTR_____(comment,extracted) TEST_EXPECT_EQUAL(test_extract(true, comment), extracted)
+
+void TEST_attribute_parser() {
+ TEST_ATTR_____("", (const char*)NULL);
+ TEST_ATTR_____("nothing here", (const char*)NULL);
+
+ TEST_ATTR_____("bla bla __ATTR__DEPRECATED(\" my reason \") more content", "__ATTR__DEPRECATED(\" my reason \")");
+ TEST_ATTR_____("bla bla __ATTR__FORMAT(pos) more content", "__ATTR__FORMAT(pos)");
+
+ TEST_ATTR_____("__ATTR__DEPRECATED", "__ATTR__DEPRECATED");
+ TEST_ATTR_____("__ATTR__FORMAT(pos)", "__ATTR__FORMAT(pos)");
+ TEST_ATTR_____("bla __ATTR__FORMAT(pos)", "__ATTR__FORMAT(pos)");
+ TEST_ATTR_____("__ATTR__FORMAT(pos) bla", "__ATTR__FORMAT(pos)");
+ TEST_ATTR_____(" __ATTR__FORMAT(pos) ", "__ATTR__FORMAT(pos)");
+
+ TEST_ATTR_____("__ATTR__FORMAT((pos)", (const char*)NULL);
+ TEST_ATTR_____("__attribute__(pos", (const char*)NULL);
+ TEST_ATTR_____("__ATTR__FORMAT(pos))", "__ATTR__FORMAT(pos)");
+ TEST_ATTR_____("__ATTR__FORMAT((pos))", "__ATTR__FORMAT((pos))");
+ TEST_ATTR_____("__ATTR__FORMAT((pos)+((sop)))", "__ATTR__FORMAT((pos)+((sop)))");
+ TEST_ATTR_____("__ATTR__FORMAT(((pos)))+(sop))", "__ATTR__FORMAT(((pos)))");
+
+ TEST_ATTR_____("bla bla __ATTR__DEPRECATED __ATTR__FORMAT(pos) more content", "__ATTR__DEPRECATED __ATTR__FORMAT(pos)");
+ TEST_ATTR_____("bla __ATTR__DEPRECATED bla more__ATTR__FORMAT(pos)content", "__ATTR__DEPRECATED __ATTR__FORMAT(pos)");
+
+ TEST_ATTR_____(" goes to header: __ATTR__NORETURN */", "__ATTR__NORETURN");
+
+ clear_found_attribute();
+}
+
+#endif // UNIT_TESTS
=====================================
AISC_MKPTPS/needs_libs.mkptypes_o
=====================================
@@ -0,0 +1,4 @@
+# libraries needed to link against AISC_MKPTPS/mkptypes.o
+
+# none
+
=====================================
SOURCE_TOOLS/Makefile
=====================================
@@ -0,0 +1,60 @@
+.SUFFIXES: .o .cxx
+
+SED:=$(ARBHOME)/SH/arb_sed
+
+all:
+ @echo "use make clean"
+
+# --------------------------------------------------------------------------------
+
+OBJECTS=arb_main_cpp.o arb_main_c.o
+
+ARB_MAIN_DEPENDS=Makefile arb_main.h
+
+arb_main_cpp.o: arb_main.cxx $(ARB_MAIN_DEPENDS)
+ $(A_CXX) $(cflags) $(cxxflags) -c $< -o $@ $(CXX_INCLUDES) $(POST_COMPILE)
+
+arb_main_c.o: arb_main.c $(ARB_MAIN_DEPENDS) arb_main.cxx
+ $(A_CC) $(cflags) -c $< -o $@ $(CC_INCLUDES) $(POST_COMPILE)
+
+mainwrapper: $(OBJECTS)
+
+# --------------------------------------------------------------------------------
+
+clean:
+ rm -f stamp.* valgrind2grep.lst postcompile.sav $(OBJECTS)
+
+valgrind_update:
+ ./arb_valgrind update
+
+# --------------------------------------------------------------------------------
+
+# library dependencies generated here always use dynamic libnames,
+# even if LINK_STATIC=1 defined in ../Makefile at LINK_STATIC
+#
+# The files generated here are not used yet (so the above does not matter)
+# They are intended to be used to link all ARB binaries
+# (instead of using explicit link commands in ../Makefile)
+
+% : %.tmp
+ ./mv_if_diff $< $@
+
+CORE_LIB=lib/libCORE.so
+
+TMP=dep.alltargets.tmp.tmp
+
+dep.alltargets.tmp: Makefile needed_libs.pl
+ LINK_STATIC=0;./needed_libs.pl -U -I -F $(CORE_LIB) > $(TMP)
+ $(SED) -e 's/ /\n/g' < $(TMP) > $@
+ rm $(TMP)
+ echo $(CORE_LIB) >>$@
+
+dep.libtargets: dep.alltargets
+ grep -E '\.(a|o|so)' $< > $@ || true
+
+dep.4dummy.tmp: dep.libtargets
+ ./gen_dep.pl dummy <$< >$@
+
+libdepends: dep.4dummy
+
+
=====================================
SOURCE_TOOLS/Makefile.commitbuild
=====================================
@@ -0,0 +1,34 @@
+
+MAIN_MAKE=$(MAKE) -C $(ARBHOME)
+
+REV_CHECK=$(ARBHOME)/SOURCE_TOOLS/rev_check.sh
+
+SUCCEEDED_REVISION:=$(shell $(REV_CHECK) last_succeeded)
+CURRENT_REVISION:=$(shell $(REV_CHECK) current)
+
+ifeq ($(SUCCEEDED_REVISION),$(CURRENT_REVISION))
+UPTODATE=1
+else
+UPTODATE=0
+endif
+
+
+build_CTARGET:
+ifeq ($(CTARGET),)
+ @echo "Error: You have to pass CTARGET to Makefile"
+ false
+else
+ @echo "Last success: '$(SUCCEEDED_REVISION)'"
+ @echo "Current rev: '$(CURRENT_REVISION)'"
+# @echo "Uptodate: '$(UPTODATE)'"
+ifeq ($(UPTODATE),0)
+ @echo "Need to make '$(CTARGET)'"
+ +$(MAIN_MAKE) $(CTARGET)
+ $(REV_CHECK) set_succeeded
+else
+ @echo "Already did a successful '$(CTARGET)' for [$(SUCCEEDED_REVISION)]"
+endif
+endif
+
+reset:
+ $(REV_CHECK) reset
=====================================
SOURCE_TOOLS/arb_main.c
=====================================
@@ -0,0 +1 @@
+#include "arb_main.cxx"
=====================================
SOURCE_TOOLS/arb_main.cxx
=====================================
@@ -0,0 +1,11 @@
+// main-wrapper
+
+#include <arb_main.h>
+
+int ARB_main(int argc, char *argv[]);
+int main(int argc, char **argv) {
+ // this is the only main() we like in production code
+ // other main()'s occur in test-code
+ start_of_main();
+ return ARB_main(argc, argv);
+}
=====================================
SOURCE_TOOLS/arb_main.h
=====================================
@@ -0,0 +1,76 @@
+// ================================================================ //
+// //
+// File : arb_main.h //
+// Purpose : code executed at start of main() //
+// //
+// Coded by Ralf Westram (coder at reallysoft.de) in February 2014 //
+// http://www.arb-home.de/ //
+// //
+// ================================================================ //
+
+#ifndef ARB_MAIN_H
+#define ARB_MAIN_H
+
+#include <locale.h>
+
+static void start_of_main() {
+ // const char *USER_LOCALE = ""; // -> use user-defined locale
+ // const char *USER_LOCALE = "de_DE.UTF-8"; // use german locale
+
+
+ // gtk apparently calls 'setlocale(LC_ALL, "");'
+ // @@@ we should already call it here, to make ARB-motif-version behave samesame.
+
+ // --------------------------------------------------------------------------------
+ // Fails-counts mentioned below were determined under ubuntu 13.10/64bit.
+ // Make sure only one section is enabled!
+
+#if 1
+ // enabling this section does not fail any unit test
+ setlocale(LC_ALL, "C");
+ // overwritten as soon as gtk-GUI starts (causing wrong behavior throughout ARB)
+#endif
+
+#if 0
+ // enabling this section does not fail any unit test
+ setlocale(LC_ALL, USER_LOCALE);
+ setlocale(LC_NUMERIC, "C");
+#endif
+
+#if 0
+ // enabling this section does not fail any unit test
+ setlocale(LC_ALL, "C");
+ setlocale(LC_COLLATE, USER_LOCALE);
+ setlocale(LC_CTYPE, USER_LOCALE);
+ setlocale(LC_MESSAGES, USER_LOCALE);
+ setlocale(LC_MONETARY, USER_LOCALE);
+ setlocale(LC_TIME, USER_LOCALE);
+#endif
+
+
+#if 0
+ // enabling this section fails 57 unit tests (for german USER_LOCALE)
+ setlocale(LC_ALL, USER_LOCALE);
+#endif
+
+#if 0
+ // enabling this section fails 57 unit tests (for german USER_LOCALE)
+ setlocale(LC_COLLATE, "C");
+ setlocale(LC_CTYPE, "C");
+ setlocale(LC_MESSAGES, "C");
+ setlocale(LC_MONETARY, "C");
+ setlocale(LC_NUMERIC, USER_LOCALE);
+ setlocale(LC_TIME, "C");
+#endif
+
+#if 0
+ // enabling this section fails 57 unit tests (for german USER_LOCALE)
+ // (fails 57 unit tests under ubuntu 13.10, centos 5 and 6)
+ setlocale(LC_ALL, "C");
+ setlocale(LC_NUMERIC, USER_LOCALE);
+#endif
+}
+
+#else
+#error arb_main.h included twice
+#endif // ARB_MAIN_H
=====================================
TEMPLATES/arb_early_check.h
=====================================
@@ -0,0 +1,35 @@
+// ================================================================ //
+// //
+// File : arb_early_check.h //
+// Purpose : early check for 32/64bit mismatch //
+// //
+// Coded by Ralf Westram (coder at reallysoft.de) in December 2012 //
+// Institute of Microbiology (Technical University Munich) //
+// http://www.arb-home.de/ //
+// //
+// ================================================================ //
+
+#ifndef ARB_EARLY_CHECK_H
+#define ARB_EARLY_CHECK_H
+
+#ifndef STATIC_ASSERT_H
+#include "static_assert.h"
+#endif
+
+// --------------------------------------------------------------------------------
+// if any of the assertions below fails, then ...
+//
+// - edit ../config.makefile and correct ARB_64 to match your machine
+// - make clean
+// - make all
+
+#if defined(ARB_64)
+STATIC_ASSERT_ANNOTATED(sizeof(void*) == 8, "You cannot compile a 64bit-ARB on a 32bit-machine");
+#else // !defined(ARB_64)
+STATIC_ASSERT_ANNOTATED(sizeof(void*) == 4, "You cannot compile a 32bit-ARB on a 64bit-machine");
+#endif
+
+
+#else
+#error arb_early_check.h included twice
+#endif // ARB_EARLY_CHECK_H
=====================================
TEMPLATES/arb_simple_assert.h
=====================================
@@ -0,0 +1,28 @@
+// ============================================================ //
+// //
+// File : arb_simple_assert.h //
+// Purpose : simple assert (independent from libCORE) //
+// //
+// Coded by Ralf Westram (coder at reallysoft.de) in June 2013 //
+// Institute of Microbiology (Technical University Munich) //
+// http://www.arb-home.de/ //
+// //
+// ============================================================ //
+
+#ifndef ARB_SIMPLE_ASSERT_H
+#define ARB_SIMPLE_ASSERT_H
+
+#if !defined(SIMPLE_ARB_ASSERT)
+#error you have to define SIMPLE_ARB_ASSERT in Makefile and pass it to compiler and makedepend
+// please DO NOT define SIMPLE_ARB_ASSERT in code
+#endif
+
+#ifndef ARB_ASSERT_H
+#include <arb_assert.h>
+#else
+#error included arb_simple_assert.h too late (arb_assert.h already has been included)
+#endif
+
+#else
+#error arb_simple_assert.h included twice
+#endif // ARB_SIMPLE_ASSERT_H
View it on GitLab: https://salsa.debian.org/med-team/libarb/compare/1557d956cfd2fe72f78c443e3a65637a4df3f1fa...030a422d48f58956f8e03a32db2aa60123db74c8
--
View it on GitLab: https://salsa.debian.org/med-team/libarb/compare/1557d956cfd2fe72f78c443e3a65637a4df3f1fa...030a422d48f58956f8e03a32db2aa60123db74c8
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20190607/d39079fb/attachment-0001.html>
More information about the debian-med-commit
mailing list