PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/Macaulay2-1.4-r12617/Macaulay2/html-check-links/grammar.y

#
Happy | 190 lines | 169 code | 21 blank | 0 comment | 0 complexity | 770688ea01bb9f300de0c0bb74ab09a5 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. /* Copyright 1993 by Daniel R. Grayson */
  2. /* declarations */
  3. %{
  4. #include "html-check-links.h"
  5. #include "buffer.h"
  6. #include "grammar.h"
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <ctype.h>
  11. extern unsigned lastcount;
  12. typedef struct { int lineno, column; char *opener; } location;
  13. BUFFER(location)
  14. locationbuf openings;
  15. static void opening(char *opener) {
  16. location t;
  17. t.lineno = lineno;
  18. t.column = column-lastcount;
  19. t.opener = opener;
  20. addlocation(&openings,t);
  21. }
  22. #define open(x,y) opening("'" #x "' unmatched by '" #y "'")
  23. #define rhs(x) opening("expression to right of '" x "' incomplete")
  24. static void closing() { rmlocation(&openings); }
  25. static void yyerror(char *);
  26. #define end_of_input 0
  27. extern int yylex (void);
  28. #include <stdarg.h>
  29. static void checkURL(char *);
  30. %}
  31. %token '<' '>' '=' WORD SRC HREF BACKGROUND
  32. %start html
  33. %% /* rules */
  34. empty : ;
  35. html : empty | html tag ;
  36. tag : '<' { opening("unmatched '<'"); }
  37. values '>' { closing(); }
  38. | error '>' ;
  39. values : empty | values value ;
  40. key : BACKGROUND | HREF | SRC ;
  41. value
  42. : WORD
  43. | WORD '=' WORD
  44. | key '=' WORD { checkURL($3); }
  45. ;
  46. %% /* programs */
  47. #ifdef MPWC
  48. char errfmt [] = " File \"%s\"; Line %d # Column %d: %s\n";
  49. char errfmtnc[] = " File \"%s\"; Line %d # %s\n";
  50. #elif defined(_WIN32) && !defined(__CYGWIN32__)
  51. char errfmt [] = "%s(%d) : column %d : %s\n";
  52. char errfmtnc[] = "%s(%d) : %s\n";
  53. #else
  54. char errfmt [] = "%s:%d:%d: %s\n";
  55. char errfmtnc[] = "%s:%d: %s\n";
  56. #endif
  57. #define VA_START_HAS_TWO_ARGS
  58. int errors = 0;
  59. void fatal(char *s,...)
  60. {
  61. char buf[200];
  62. va_list ap;
  63. #ifdef VA_START_HAS_TWO_ARGS
  64. va_start(ap,s);
  65. #else
  66. va_start(ap);
  67. #endif
  68. vsnprintf(buf,sizeof buf,s,ap);
  69. fprintf(stderr,errfmt,filename,lineno,column-lastcount,buf);
  70. fflush(stderr);
  71. va_end(ap);
  72. exit(1);
  73. }
  74. void error(char *s,...)
  75. {
  76. char buf[20000];
  77. char *err = "error: ";
  78. char new_s[strlen(s) + strlen(err) + 1];
  79. va_list ap;
  80. #ifdef VA_START_HAS_TWO_ARGS
  81. va_start(ap,s);
  82. #else
  83. va_start(ap);
  84. #endif
  85. strcpy(new_s,err);
  86. strcat(new_s,s);
  87. vsnprintf(buf,sizeof buf,new_s,ap);
  88. fprintf(stderr,errfmt,filename,lineno,column-lastcount,buf);
  89. fflush(stderr);
  90. va_end(ap);
  91. if (ERRLIMIT && ++errors > ERRLIMIT) fatal("too many errors");
  92. }
  93. void warning(char *s,...)
  94. {
  95. char buf[200];
  96. char *err = "warning: ";
  97. char new_s[strlen(s) + strlen(err) + 1];
  98. va_list ap;
  99. #ifdef VA_START_HAS_TWO_ARGS
  100. va_start(ap,s);
  101. #else
  102. va_start(ap);
  103. #endif
  104. strcpy(new_s,err);
  105. strcat(new_s,s);
  106. vsnprintf(buf,sizeof buf,new_s,ap);
  107. fprintf(stderr,errfmt,filename,lineno,column-lastcount,buf);
  108. fflush(stderr);
  109. va_end(ap);
  110. }
  111. static void printopening(location x) {
  112. char buf[100];
  113. snprintf(buf,sizeof buf," (%s)", x.opener);
  114. fprintf(stderr,errfmt,filename,x.lineno,x.column,buf);
  115. }
  116. static void yyerror(char *s) {
  117. if (yychar == 0) s = concat(s," at end of file");
  118. error(s);
  119. #if 1
  120. rscan(openings,printopening);
  121. #else
  122. if (openings.used > 0) printopening(openings.array[openings.used-1]);
  123. #endif
  124. emptylocation(&openings);
  125. }
  126. static int strseg(char *s, char *t) {
  127. while (*t) if (*s++ != *t++) return FALSE;
  128. return TRUE;
  129. }
  130. static void demangle_error(char *msg,char *s) {
  131. char *p = demangle(s);
  132. if (0 == strcmp(p,s))
  133. error("%s: %s",msg,s);
  134. else
  135. error("%s: %s ==> %s",msg,s,p);
  136. }
  137. static void checkURL(char *s0) {
  138. char *s;
  139. if (s0[0] == '"' && s0[strlen(s0)-1] == '"') s0++, s0[strlen(s0)-1]=0;
  140. else if (s0[0] == '\'' && s0[strlen(s0)-1] == '\'') s0++, s0[strlen(s0)-1]=0;
  141. s = strdup(s0);
  142. if (strseg(s,"mailto:") || strseg(s,"http://") || strseg(s,"ftp://")) {
  143. /* warning("unchecked external link: %s",s); */
  144. return;
  145. }
  146. if (strseg(s,"file://")) s += 7;
  147. {char *t; t = strrchr(s,'#'); if (t != NULL) *t = 0;}
  148. if (*s == 0) return;
  149. if (s[0] == '/' && isascii(s[1]) && isupper(s[1]) && s[2] == ':') {
  150. /* absolute path in Windows */
  151. s++;
  152. if (!abs_links) demangle_error("absolute link",s0);
  153. }
  154. else if (s[0] == '/') {
  155. /* absolute path */
  156. if (!abs_links) demangle_error("absolute link",s0);
  157. s = concat(rootname,s);
  158. }
  159. else {
  160. /* relative path */
  161. s = concat(Dirname,s);
  162. }
  163. if (-1 == access(s, R_OK)) demangle_error("broken link",s0);
  164. }
  165. /*
  166. Local Variables:
  167. compile-command: "make -C $M2BUILDDIR/Macaulay2/html-check-links "
  168. End:
  169. */