/* * * This file is part of Open Sound System. * * Copyright (C) 4Front Technologies 1996-2008. * * This this source file is released under GPL v2 license (no other versions). * See the COPYING file included in the main directory of this source * distribution for the license terms and conditions. * */ #define OSS_LICENSE "" #include #include #include #include #include #include #include #include #include #include "/tmp/buildid.h" #define MAX_ERRORS 1000 typedef struct { int err; char *sourcename; int linenum; char *msg; char *desc; } errordesc_t; errordesc_t *errors[MAX_ERRORS]; int nerrors = 0; char * strmatch (char *s, const char *pattern) { int i, l, pl; if (s == NULL || *pattern == 0) return NULL; l = strlen (s); pl = strlen (pattern); if (pl > l) return NULL; while (s && l >= pl) { int ok = 0; for (i = 0; !ok && i < pl; i++) if (s[i] != pattern[i]) { ok = 1; continue; } if (!ok) return s; s++; l--; } return NULL; } char * check_comment (FILE * f, const char *sourcename, int *linenum) { char line[4096]; int is_desc = 0; static char errorbuf[64 * 1024]; int done = 0; *errorbuf = 0; if (fgets (line, sizeof (line) - 1, f) != NULL) { char *s, *p; int l; *linenum = *linenum + 1; if ((l = strlen (line)) > 4000) { fprintf (stderr, "Too long line in %s\n", sourcename); exit (-1); } /* * Strip trailing CR and LF characters. */ s = line + l - 1; while (*s == '\n' || *s == '\r') *s-- = 0; s = line; while (*s == ' ' || *s == '\t') s++; if (s[0] != '/' || s[1] != '*') return NULL; if ((p = strmatch (s, "Errordesc:"))) { p += 10; while (*p == ' ') p++; is_desc = 1; if ((s = strmatch (p, "*/"))) { *s = 0; return p; } else { strcat (errorbuf, p); } } } /* * Handle comment continuation lines. */ while (!done && fgets (line, sizeof (line) - 1, f) != NULL) { char *s, *p; int l; *linenum = *linenum + 1; if ((l = strlen (line)) > 4000) { fprintf (stderr, "Too long line in %s\n", sourcename); exit (-1); } /* * Strip trailing CR and LF characters. */ s = line + l - 1; while (*s == '\n' || *s == '\r') *s-- = 0; s = line; while (*s == ' ' || *s == '\t' || *s == '*') s++; if (*s == '/' && s[-1] == '*') /* End of comment */ break; if ((p = strmatch (s, "Errordesc:"))) { p += 10; while (*p == ' ') p++; is_desc = 1; if ((s = strmatch (p, "*/"))) { *s = 0; if (*errorbuf != 0) strcat (errorbuf, " "); strcat (errorbuf, p); done = 1; } else { if (*errorbuf != 0) strcat (errorbuf, " "); strcat (errorbuf, p); } continue; } p = s; if ((s = strmatch (p, "*/"))) { *s = 0; if (*errorbuf != 0) strcat (errorbuf, " "); strcat (errorbuf, p); done = 1; } else { if (*errorbuf != 0) strcat (errorbuf, " "); strcat (errorbuf, p); } } if (is_desc) return errorbuf; return NULL; } void store_error (int errnum, const char *sourcename, int linenum, const char *msg, const char *desc) { errordesc_t *err; //printf("%s:%d: %05d=%s\n", sourcename, linenum, errnum, msg); if (nerrors >= MAX_ERRORS) { fprintf (stderr, "Too many errors\n"); exit (-1); } if ((err = malloc (sizeof (*err))) == NULL) { fprintf (stderr, "Too many errors defined\n"); exit (-1); } err->err = errnum; err->sourcename = strdup (sourcename); err->linenum = linenum; err->msg = strdup (msg); if (desc == NULL) err->desc = NULL; else err->desc = strdup (desc); errors[nerrors++] = err; } void parse_sourcefile (char *sourcename) { int linenum = 0; char line[4096]; FILE *f; if (*sourcename == '.') sourcename += 2; /* Skip the "./" directory prefix */ /* * Don't handle myself or oss_config.h. */ if (strcmp (basename (sourcename), "update_errors.c") == 0) return; if (strcmp (basename (sourcename), "oss_config.h") == 0) return; if ((f = fopen (sourcename, "r")) == NULL) { perror (sourcename); exit (-1); } while (fgets (line, sizeof (line) - 1, f) != NULL) { char *s; int l; linenum++; if ((l = strlen (line)) > 4000) { fprintf (stderr, "Too long line in %s\n", sourcename); exit (-1); } /* * Strip trailing CR and LF characters. */ s = line + l - 1; while (*s == '\n' || *s == '\r') *s-- = 0; if ((s = strmatch (line, "OSSERR"))) { char *p; char tmp[4096]; char tmp2[4096]; int num, thisline; s += 6; /* Skip "OSSERR" */ while (*s == ' ' || *s == '\t' || *s == '(') s++; /* * Get the error number */ p = s; while (*s >= '0' && *s <= '9') s++; while (*s == ',' || *s == ' ' || *s == '\t' || *s == '"') *s++ = 0; if (sscanf (p, "%d", &num) != 1) { fprintf (stderr, "Bad error number in %s:%d\n", sourcename, linenum); } p = s; if (*p == 0) { /* * No '"' was found. Read the continuation line. */ fgets (tmp, sizeof (tmp) - 1, f); p = tmp; while (*p == ' ' || *p == '\t' || *p == '"') p++; s = p; while (*s && *s != '"') s++; if (*s) *s++ = 0; } while (*s && *s != '"') s++; if (*s) *s++ = 0; // printf("%s:%d: %d=%s\n", sourcename, linenum, num, p); while (*s && *s != ';') s++; if (*s != ';') /* No semicolon. Discard the next line */ fgets (tmp2, sizeof (tmp2) - 1, f); *s = 0; /* * Check if the next line starts the descriptive comment */ thisline = linenum; if ((s = check_comment (f, sourcename, &linenum))) store_error (num, sourcename, thisline, p, s); else store_error (num, sourcename, thisline, p, NULL); } } fclose (f); } int compare (const void *a_, const void *b_) { const char *const *a__ = a_; const char *const *b__ = b_; const errordesc_t *a = *a__; const errordesc_t *b = *b__; if (a->err == b->err) return 0; if (a->err < b->err) return -1; return 1; } int main (int argc, char *argv[]) { int i, status = 0; for (i = 1; i < argc; i++) { parse_sourcefile (argv[i]); } qsort (errors, nerrors, sizeof (errordesc_t *), compare); for (i = 0; i < nerrors; i++) { if (errors[i]->err == 0) { fprintf (stderr, "%s:%d: Error number is zero\n", errors[i]->sourcename, errors[i]->linenum); status = 1; continue; } if (i > 0 && errors[i]->err == errors[i - 1]->err) { fprintf (stderr, "%s:%d: duplicate error %05d\n", errors[i]->sourcename, errors[i]->linenum, errors[i]->err); status = 1; continue; } if (i < nerrors - 1 && errors[i]->err == errors[i + 1]->err) { fprintf (stderr, "%s:%d: duplicate error %05d\n", errors[i]->sourcename, errors[i]->linenum, errors[i]->err); status = 1; continue; } } printf ("\n"); printf ("OSS run time error list for OSS v%s\n", OSS_VERSION_STRING); printf ("\n"); printf ("

OSS run time error list for OSS v%s

\n", OSS_VERSION_STRING); printf ("\n"); printf ("/\n"); for (i = 0; i < nerrors; i++) { #if 1 printf ("\n"); #else printf ("

%05d: %s

\n", errors[i]->err, errors[i]->msg); if (errors[i]->desc != NULL) printf ("
  • %s
\n", errors[i]->desc); #endif } printf ("
CodeDescription
%05d%s\n", errors[i]->err, errors[i]->msg); if (errors[i]->desc != NULL) printf ("
%s\n", errors[i]->desc); printf ("
\n"); printf ("\n"); printf ("\n"); exit (status); }