warn.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Warnings.
  3. */
  4. /* $Id$ */
  5. #include <stdio.h>
  6. #include "logging.h"
  7. #include "global.h"
  8. #include "log.h"
  9. #include "alloc.h"
  10. #include "warn.h"
  11. #include "linfil.h"
  12. extern FILE *mess_fp; /* from io.c */
  13. extern char *trap2text(); /* from trap.c */
  14. /******** The warnings ********/
  15. struct warn_msg {
  16. char *wm_text;
  17. int wm_nr;
  18. };
  19. #define WMASK 0x5555 /* powers of 4 */
  20. PRIVATE struct warn_msg warn_msg[] = {
  21. #include "warn_msg" /* generated from $(EM)/doc/int */
  22. {0, 0} /* sentinel */
  23. };
  24. PRIVATE char *warn_text[WMSG+1];
  25. init_wmsg()
  26. {
  27. register int i;
  28. register struct warn_msg *wmsg;
  29. for (i = 0; i <= WMSG; i++) {
  30. warn_text[i] = "*** Unknown warning (internal error) ***";
  31. }
  32. for (wmsg = &warn_msg[0]; wmsg->wm_nr; wmsg++) {
  33. warn_text[wmsg->wm_nr] = wmsg->wm_text;
  34. }
  35. }
  36. /******** The warning counters ********/
  37. struct warn_cnt {
  38. struct warn_cnt *next;
  39. ptr wc_fil; /* file name pointer */
  40. long wc_lin; /* line number */
  41. long wc_cnt; /* the counter */
  42. };
  43. PRIVATE struct warn_cnt *warn_cnt[WMSG];
  44. PRIVATE char warnmask[WMSG];
  45. PRIVATE long count_wrn(nr)
  46. int nr;
  47. { /* returns the occurrence counter for the warning with number
  48. nr; keeps track of the warnings, sorted by warning number,
  49. file name and line number.
  50. */
  51. register struct warn_cnt **warn_hook = &warn_cnt[nr];
  52. register struct warn_cnt *wrn;
  53. while (wrn = *warn_hook) {
  54. if (wrn->wc_fil == FIL && wrn->wc_lin == LIN) {
  55. return ++wrn->wc_cnt;
  56. }
  57. warn_hook = &wrn->next;
  58. }
  59. wrn = (struct warn_cnt *)
  60. Malloc((size) sizeof (struct warn_cnt), (char *)0);
  61. if (!wrn) {
  62. /* no problem */
  63. return 1;
  64. }
  65. *warn_hook = wrn;
  66. wrn->next = 0;
  67. wrn->wc_fil = FIL;
  68. wrn->wc_lin = LIN;
  69. wrn->wc_cnt = 1;
  70. return 1;
  71. }
  72. /******** The handling ********/
  73. #define wmask_on(i) (warnmask[i])
  74. PRIVATE int latest_warning_printed; /* set if ... */
  75. /*ARGSUSED*/
  76. do_warn(nr, L, F)
  77. int nr;
  78. int L;
  79. char *F;
  80. {
  81. latest_warning_printed = 0;
  82. if (nr < WMSG) {
  83. if (!wmask_on(nr)) {
  84. register long wrn_cnt = count_wrn(nr);
  85. register char *wmsgtxt = warn_text[nr];
  86. LOG(("@w1 warning: %s [%s: %d]", wmsgtxt, F, L));
  87. if ( /* wrn_cnt is a power of two */
  88. !((wrn_cnt-1) & wrn_cnt)
  89. && /* and it is the right power of two */
  90. (WMASK & wrn_cnt)
  91. ) {
  92. fprintf(mess_fp,
  93. "(Warning %d, #%ld): %s at %s\n",
  94. nr, wrn_cnt, wmsgtxt, position());
  95. latest_warning_printed = 1;
  96. }
  97. }
  98. }
  99. else {
  100. /* actually a trap number */
  101. nr -= WMSG;
  102. fprintf(mess_fp, "(Warning): Trap occurred - %s at %s\n",
  103. trap2text(nr), position());
  104. }
  105. }
  106. #ifdef LOGGING
  107. warningcont(nr)
  108. int nr;
  109. {
  110. /* continued warning */
  111. if (latest_warning_printed) {
  112. if (!wmask_on(nr)) {
  113. register char *wmsgtxt = warn_text[nr];
  114. LOG(("@w1 warning cont.: %s", wmsgtxt));
  115. fprintf(mess_fp,
  116. "(Warning %d, cont.): %s at %s\n",
  117. nr, wmsgtxt, position());
  118. }
  119. }
  120. }
  121. #endif /* LOGGING */
  122. set_wmask(i)
  123. int i;
  124. {
  125. if (i < WMSG) {
  126. warnmask[i] = 1;
  127. }
  128. }