root/cgi/html.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. readable_time_static
  2. readable_time
  3. html_transcnt
  4. html_catsz
  5. html_conv_tab
  6. html_encode
  7. html_make_link
  8. vhtml
  9. html
  10. html_page_begin
  11. html_table_begin
  12. html_table_row
  13. html_table_end
  14. html_print_err
  15. html_page_end

   1 #ifndef __cgi_html__
   2 #define __cgi_html__ 1
   3 
   4 #include "cgi.h"
   5 
   6 #include <stdio.h>
   7 #include <stdlib.h>
   8 #include <string.h>
   9 #include <stdarg.h>
  10 
  11 extern const char *extra_head;
  12 extern const char *my_header;
  13 extern const char *my_footer;
  14 extern FILE *capture;
  15 
  16 
  17 #ifndef MY_DATE_FMT
  18 # define MY_DATE_FMT "%Y.%m.%d"
  19 #endif
  20 #ifndef MY_LONG_DATE_FMT
  21 # define MY_LONG_DATE_FMT "%Y.%m.%d %H:%M %z"
  22 #endif
  23 
  24 
  25 static char *
  26 readable_time_static(time_t t, const char *fmt)
  27 {
  28         char *ts = my_malloc(MINB);
  29 
  30         if (!ts) return NULL;
  31 
  32         strftime(ts, MINB, fmt, localtime(&t));
  33 
  34         return ts;
  35 }
  36 
  37 
  38 static char *
  39 readable_time(time_t t)
  40 {
  41 #ifdef NO_DATE_AGO
  42         return readable_time_static(t);
  43 #else
  44         char *ts = my_malloc(MINB);
  45         time_t n = time(NULL) - t;
  46 # ifndef NO_DATE_COLOR
  47 #  define SEC_RB "<span class=\"cgi-rdate-sec\">"
  48 #  define MIN_RB "<span class=\"cgi-rdate-min\">"
  49 #  define HRT_RB "<span class=\"cgi-rdate-hour\">"
  50 #  define DAY_RB "<span class=\"cgi-rdate-day\">"
  51 #  define TC_RE "</span>"
  52 # else
  53 #  define SEC_RB ""
  54 #  define HRT_RB ""
  55 #  define MIN_RB ""
  56 #  define DAY_RB ""
  57 #  define TC_RE ""
  58 # endif
  59 
  60         if (!ts) return NULL;
  61 
  62         if (n < 60)
  63                 snprintf(ts, MINB, SEC_RB "%ds ago" TC_RE, (int)n);
  64         else if (n < 3600)
  65                 snprintf(ts, MINB, MIN_RB "%dm ago" TC_RE, (int)(n / 60));
  66         else if (n < 86400)
  67                 snprintf(ts, MINB, HRT_RB "%dh ago" TC_RE, (int)(n / 3600));
  68         else if (n < 2419200)
  69                 snprintf(ts, MINB, DAY_RB "%dd ago" TC_RE, (int)(n / 86400));
  70         else {
  71                 my_free(ts);
  72                 return readable_time_static(t, MY_DATE_FMT);
  73         }
  74 
  75         return ts;
  76 #endif
  77 }
  78 
  79 
  80 static size_t
  81 html_transcnt(const char *s, int a, ...)
  82 {
  83         va_list ap;
  84         size_t c = 1;
  85         int i, tc;
  86 
  87         while (*s != '\0') {
  88                 va_start(ap, a);
  89                 for (tc = 1, i = 0; i < a; i++)
  90                         if (*s == va_arg(ap, int)) {
  91                                 tc = va_arg(ap, int);
  92                         } else (void)va_arg(ap, int);
  93                 va_end(ap);
  94                 c += tc; s++;
  95         }
  96 
  97         return c;
  98 }
  99 
 100 
 101 static size_t
 102 html_catsz(const char *s, ...)
 103 {
 104         va_list ap;
 105         size_t t = 0;
 106         int i;
 107 
 108         va_start(ap, s);
 109         for (i = 0; i < strlen(s); i++) {
 110                 switch (s[i]) {
 111                 case 's': t += va_arg(ap, size_t); break;
 112                 case 'r': t += strlen(va_arg(ap, const char *)) + 1; break;
 113                 default : break;
 114                 }
 115         }
 116         va_end(ap);
 117 
 118         return t;
 119 }
 120 
 121 
 122 static char *
 123 html_conv_tab(const char *line, size_t tw)
 124 {
 125         size_t i = 0, tsz = html_transcnt(line, 1, '\t', 8);
 126         char *cp, *t = my_malloc(tsz);
 127         char *lim = t + tsz;
 128 
 129         if (!t) return NULL;
 130 
 131 #define bputc(b, m, c) ((b) < (m) ? (*(b)++ = (c)) : (*(b) = '\0'))
 132         cp = t; while (*line != '\0') {
 133                 int i2, ci = 1;
 134                 if (*line == '\t') {
 135                         ci = tw - (i % tw);
 136                         for (i2 = 0; i2 < ci; i2++)
 137                                 bputc(cp, lim, ' ');
 138                 } else bputc(cp, lim, *line);
 139                 i += ci; line++;
 140         }
 141         bputc(cp, lim, '\0');
 142 
 143         return t;
 144 }
 145 
 146 
 147 #define html_encode_cnt(s) (html_transcnt((s), 3, '<', 4, '>', 4, '&', 5))
 148 static char *
 149 html_encode(const char *s)
 150 {
 151         size_t i, a, bsz = html_encode_cnt(s);
 152         int c;
 153         char *cp, *cp2, *st = my_strdup(s), *t = my_malloc(bsz);
 154 
 155         if (!(t && st)) return NULL;
 156         *t = '\0';
 157 
 158         for (cp = st;;) {
 159                 /* cut up s into already-valid spans */
 160                 a = strcspn(cp2 = cp, "<>&");
 161                 c = *(cp += a);
 162                 *(cp++) = '\0';
 163 
 164                 /* copy valid section directly */
 165                 strncat(t, cp2, bsz);
 166 
 167                 /* process invalid character */
 168                 switch (c) {
 169                 case '\0': goto exit_encode;
 170                 case '<' : strncat(t, "&lt;" , bsz); break;
 171                 case '>' : strncat(t, "&gt;" , bsz); break;
 172                 case '&' : strncat(t, "&amp;", bsz); break;
 173                 }
 174         }
 175  exit_encode:
 176         my_free(st);
 177         return t;
 178 }
 179 
 180 
 181 static char *
 182 html_make_link(const char *href, const char *title)
 183 {
 184         const char *fmt = "<a href=\"%s\">%s</a>";
 185         size_t bsz = html_catsz("srr", html_encode_cnt(href), title, fmt);
 186         char *ht, *t = my_malloc(bsz);
 187 
 188         if (!t) return NULL;
 189 
 190         ht = html_encode(href);
 191 
 192         snprintf(t, bsz, fmt, ht, title);
 193 
 194         my_free(ht);
 195 
 196         return t;
 197 }
 198 
 199 
 200 static void
 201 vhtml(const char *fmt, va_list ap)
 202 {
 203         vfprintf(capture, fmt, ap);
 204 }
 205 
 206 
 207 static void
 208 html(const char *fmt, ...)
 209 {
 210         va_list ap;
 211         va_start(ap, fmt);
 212         vhtml(fmt, ap);
 213         va_end(ap);
 214 }
 215 
 216 
 217 static void
 218 html_page_begin(char *title)
 219 {
 220         html("<!DOCTYPE html>\n\
 221 <html>\
 222 <head>\
 223 <meta charset=\"UTF-8\">\n\
 224 <title>%s</title>\n\
 225 %s</head>\n\
 226 <body>\n\
 227 %s", html_encode(title), extra_head, my_header);
 228 }
 229 
 230 
 231 static void
 232 html_table_begin(int n, ...)
 233 {
 234         int i;
 235         va_list ap;
 236 
 237         va_start(ap, n);
 238         html("<table>\n");
 239         if (n > 0) {
 240                 html("  <tr>\n");
 241                 for (i = 0; i < n; i++)
 242                         html("    <th>%s</th>\n", va_arg(ap, char *));
 243                 html("  </tr>\n");
 244         }
 245         va_end(ap);
 246 }
 247 
 248 
 249 static void
 250 html_table_row(int n, ...)
 251 {
 252         int i;
 253         va_list ap;
 254 
 255         va_start(ap, n);
 256         html("  <tr>\n");
 257         for (i = 0; i < n; i++)
 258                 html("    <td>%s</td>\n", va_arg(ap, char *));
 259         html("  </tr>\n");
 260         va_end(ap);
 261 }
 262 
 263 
 264 static void
 265 html_table_end(void)
 266 {
 267         html("</table>\n");
 268 }
 269 
 270 
 271 static void
 272 html_print_err(const char *fmt, ...)
 273 {
 274         va_list ap;
 275         va_start(ap, fmt);
 276         html("<div class=\"cgi-error\"><p>");
 277         vhtml(fmt, ap);
 278         html("</p></div>\n");
 279         va_end(ap);
 280 }
 281 
 282 
 283 static void
 284 html_page_end(void)
 285 {
 286         html("%s</body></html>\n", my_footer);
 287 }
 288 
 289 
 290 #endif

/* [previous][next][first][last][top][bottom][index][help] */