Ejemplo n.º 1
0
void print_ansi(char *buf, size_t buflen, buffered_output_t *output)
{
	unsigned int font_style = 0;
	unsigned int ansi_state;
	unsigned int ansi_val[STRLEN];
	int ival = 0;
	size_t i;
	char *ptr = buf;
	char *ansi_begin;
	char *ansi_end;
	
	if (ptr == NULL)
		return;
	STATE_ZERO(ansi_state);
	bzero(ansi_val, sizeof(ansi_val));
	for (i = 0; i < buflen; i++)
	{
		if (STATE_ISSET(ansi_state, STATE_NEW_LINE))
		{
			STATE_CLR(ansi_state, STATE_NEW_LINE);
			if (i < (buflen - 1) && (buf[i] == ':' && buf[i+1] == ' '))
			{
				STATE_SET(ansi_state, STATE_QUOTE_LINE);
				if (STATE_ISSET(ansi_state, STATE_FONT_SET))
					output->output("</font>", 7, output);
				/* set quoted line styles */
				STYLE_SET(font_style, FONT_STYLE_QUOTE);
				STYLE_SET_FG(font_style, FONT_COLOR_QUOTE);
				STYLE_CLR_BG(font_style);
				print_font_style(font_style, output);
				output->output(&buf[i], 1, output);
				STATE_SET(ansi_state, STATE_FONT_SET);
				STATE_CLR(ansi_state, STATE_ESC_SET);
				/* clear ansi_val[] array */
				bzero(ansi_val, sizeof(ansi_val));
				ival = 0;
				continue;
			}
			else
				STATE_CLR(ansi_state, STATE_QUOTE_LINE);
		}
		if (i < (buflen - 1) && (buf[i] == 0x1b && buf[i+1] == '['))
		{
			if (STATE_ISSET(ansi_state, STATE_ESC_SET))
			{
				/* *[*[ or *[13;24*[ */
				size_t len;
				ansi_end = &buf[i - 1];
				len = ansi_end - ansi_begin + 1;
				print_raw_ansi(ansi_begin, len, output);
			}
			STATE_SET(ansi_state, STATE_ESC_SET);
			ansi_begin = &buf[i];
			i++; /* skip the next '[' character */
		}
		else if (buf[i] == '\n')
		{
			if (STATE_ISSET(ansi_state, STATE_ESC_SET))
			{
				/* *[\n or *[13;24\n */
				size_t len;
				ansi_end = &buf[i - 1];
				len = ansi_end - ansi_begin + 1;
				print_raw_ansi(ansi_begin, len, output);
				STATE_CLR(ansi_state, STATE_ESC_SET);
			}
			if (STATE_ISSET(ansi_state, STATE_QUOTE_LINE))
			{
				/* end of a quoted line */
				output->output("</font>", 7, output);
				STYLE_CLR(font_style, FONT_STYLE_QUOTE);
				STATE_CLR(ansi_state, STATE_FONT_SET);
			}
			output->output("<br />\n", 7, output);
			STATE_CLR(ansi_state, STATE_QUOTE_LINE);
			STATE_SET(ansi_state, STATE_NEW_LINE);
		}
		else
		{
			if (STATE_ISSET(ansi_state, STATE_ESC_SET))
			{
				if (buf[i] == 'm')
				{
					/* *[0;1;4;31m */
					if (STATE_ISSET(ansi_state, STATE_FONT_SET))
					{
						output->output("</font>", 7, output);
						STATE_CLR(ansi_state, STATE_FONT_SET);
					}
					if (i < buflen - 1)
					{
						generate_font_style(&font_style, ansi_val, ival+1);
						if (STATE_ISSET(ansi_state, STATE_QUOTE_LINE))
							STYLE_SET(font_style, FONT_STYLE_QUOTE);
						print_font_style(font_style, output);
						STATE_SET(ansi_state, STATE_FONT_SET);
						STATE_CLR(ansi_state, STATE_ESC_SET);
						/*STYLE_ZERO(font_style);*/
						/* clear ansi_val[] array */
						bzero(ansi_val, sizeof(ansi_val));
						ival = 0;
					}
				}
				else if (isalpha(buf[i]))
				{
					/* *[23;32H */
					/* ignore it */
					STATE_CLR(ansi_state, STATE_ESC_SET);
					STYLE_ZERO(font_style);
					/* clear ansi_val[] array */
					bzero(ansi_val, sizeof(ansi_val));
					ival = 0;
					continue;
				}
				else if (buf[i] == ';')
				{
					if (ival < sizeof(ansi_val) - 1)
					{
						ival ++; /* go to next ansi_val[] element */
						ansi_val[ival] = 0;
					}
				}
				else if (buf[i] >= '0' && buf[i] <= '9')
				{
					ansi_val[ival] *= 10;
					ansi_val[ival] += (buf[i] - '0');
				}
				else
				{
					/* *[1;32/XXXX or *[* or *[[ */
					/* not a valid ANSI string, just output it */
					size_t len;
					
					ansi_end = &buf[i];
					len = ansi_end - ansi_begin + 1;
					print_raw_ansi(ansi_begin, len, output);
					STATE_CLR(ansi_state, STATE_ESC_SET);
					/* clear ansi_val[] array */
					bzero(ansi_val, sizeof(ansi_val));
					ival = 0;
				}
				
			}
			else
				print_raw_ansi(&buf[i], 1, output);
		}
	}
	if (STATE_ISSET(ansi_state, STATE_FONT_SET))
	{
		output->output("</font>", 7, output);
		STATE_CLR(ansi_state, STATE_FONT_SET);
	}
	flush_buffer(output);
}
Ejemplo n.º 2
0
int
token_next (struct tokenizer *t, char **tok, enum token_type *type)
{
  enum token_type etype = TOKEN_TYPE_SYMBOL;

  dstring_trunc (&t->tok);
  for (;;) {
    switch (chars_get (t)) {
      case 0:
        if (STATE_ISSET (STATE_STRING)) return 0;
        if (STATE_ISSET (STATE_ESCAPE)) return 0;
        if (STATE_ISSET (STATE_COMMENT)) return 0;
        etype = TOKEN_TYPE_EOF;
        goto END;
      case -1: return 0;
      default: break;
    }
    switch (t->ch_cur) {
      case ';':
        if (STATE_ISSET (STATE_STRING) || STATE_ISSET (STATE_ESCAPE)) {
          if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
          break;
        }
        if (STATE_ISSET (STATE_COMMENT)) break;
        STATE_SET (STATE_COMMENT);
        break;
      case '\n':
        if (STATE_ISSET (STATE_COMMENT)) {
          STATE_UNSET (STATE_COMMENT);
          break;
        }
        t->line++;
      case ' ':
      case '\t':
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (STATE_ISSET (STATE_ESCAPE)) STATE_UNSET (STATE_ESCAPE);
        if (STATE_ISSET (STATE_STRING)) {
          if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
        } else {
          if (t->tok.len) goto END;
        }
        break;
      case '"':
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (STATE_ISSET (STATE_STRING)) {
          if (STATE_ISSET (STATE_ESCAPE)) {
            if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
            STATE_UNSET (STATE_ESCAPE);
          } else {
            STATE_UNSET (STATE_STRING);
            goto END;
          }
        } else {
          STATE_SET (STATE_STRING);
          etype = TOKEN_TYPE_STRING;
        }
        break;
      case '\\':
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (STATE_ISSET (STATE_STRING)) {
          if (STATE_ISSET (STATE_ESCAPE)) {
            if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
            STATE_UNSET (STATE_ESCAPE);
          } else {
            STATE_SET (STATE_ESCAPE);
          }
        }
        break;
      case '(':
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
        if (!STATE_ISSET (STATE_STRING)) {
          etype = TOKEN_TYPE_PAREN_OPEN;
          goto END;
        }
        break;
      case ')':
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
        if (!STATE_ISSET (STATE_STRING)) {
          etype = TOKEN_TYPE_PAREN_CLOSE;
          goto END;
        }
        break;
      default:
        if (STATE_ISSET (STATE_COMMENT)) break;
        if (STATE_ISSET (STATE_ESCAPE)) STATE_UNSET (STATE_ESCAPE);
        if (!dstring_catb (&t->tok, &t->ch_cur, 1)) return 0;
        switch (t->ch_next) {
          case ')':
          case '(':
          case '"':
            if (!STATE_ISSET (STATE_STRING)) goto END;
          default: break;
        }
        break;
    }
  }

END:
  dstring_0 (&t->tok);
  *tok = t->tok.s;
  *type = etype;
  return 1;
}
Ejemplo n.º 3
0
static void output_ansi_nforum(char *buf, size_t buflen,
                      buffered_output_t * output, zval *attachment)
{
    unsigned int font_style = 0;
    unsigned int ansi_state;
    unsigned int ansi_val[STRLEN];
    int ival = 0;
    size_t i;
    bool att = false;
    char *ansi_begin = NULL;
    char *ansi_end;
    size_t article_len = buflen;

    if (buf == NULL)
        return;

    STATE_ZERO(ansi_state);
    bzero(ansi_val, sizeof(ansi_val));

    for (i = 0; i < article_len; i++) {
        if (buf[i] == '\0') { //assume ATTACHMENT_PAD[0] is '\0'
            if (article_len - i >= ATTACHMENT_SIZE + sizeof(int) + 2) {
                if (!memcmp(buf + i, ATTACHMENT_PAD, ATTACHMENT_SIZE)) {
                    att = true;
                    break;
                }
            }
        }
        if (STATE_ISSET(ansi_state, STATE_NEW_LINE)) {
            STATE_CLR(ansi_state, STATE_NEW_LINE);
            if (i < (buflen - 1) && !STATE_ISSET(ansi_state,STATE_TEX_SET) && (buf[i] == ':' && buf[i + 1] == ' ')) {
                STATE_SET(ansi_state, STATE_QUOTE_LINE);
                if (STATE_ISSET(ansi_state, STATE_FONT_SET))
                    BUFFERED_OUTPUT(output, "</font>", 7);
                /*
                 * set quoted line styles
                 */
                STYLE_SET(font_style, FONT_STYLE_QUOTE);
                STYLE_SET_FG(font_style, FONT_COLOR_QUOTE);
                STYLE_CLR_BG(font_style);
                print_font_style(font_style, output);
                BUFFERED_OUTPUT(output, &buf[i], 1);
                STATE_SET(ansi_state, STATE_FONT_SET);
                STATE_CLR(ansi_state, STATE_ESC_SET);
                /*
                 * clear ansi_val[] array
                 */
                bzero(ansi_val, sizeof(ansi_val));
                ival = 0;
                continue;
            } else
                STATE_CLR(ansi_state, STATE_QUOTE_LINE);
        }
        /*
        * is_tex 情况下,\[upload 优先匹配 \[ 而不是 [upload
        * is_tex 情况下应该还有一个问题是 *[\[ 等,不过暂时不管了 - atppp
        */
        if (i < (buflen - 1) && !STATE_ISSET(ansi_state,STATE_TEX_SET) && (buf[i] == 0x1b && buf[i + 1] == '[')) {
            if (STATE_ISSET(ansi_state, STATE_ESC_SET)) {
                /*
                 *[*[ or *[13;24*[ */
                size_t len;

                ansi_end = &buf[i - 1];
                len = ansi_end - ansi_begin + 1;
                print_raw_ansi(ansi_begin, len, output);
            }
            STATE_SET(ansi_state, STATE_ESC_SET);
            ansi_begin = &buf[i];
            i++;                /* skip the next '[' character */
        } else if (buf[i] == '\n') {
            if (STATE_ISSET(ansi_state, STATE_ESC_SET)) {
                /*
                 *[\n or *[13;24\n */
                size_t len;

                ansi_end = &buf[i - 1];
                len = ansi_end - ansi_begin + 1;
                print_raw_ansi(ansi_begin, len, output);
                STATE_CLR(ansi_state, STATE_ESC_SET);
            }
            if (STATE_ISSET(ansi_state, STATE_QUOTE_LINE)) {
                /*
                 * end of a quoted line
                 */
                BUFFERED_OUTPUT(output, " </font>", 8);
                STYLE_CLR(font_style, FONT_STYLE_QUOTE);
                STATE_CLR(ansi_state, STATE_FONT_SET);
            }
            if (!STATE_ISSET(ansi_state,STATE_TEX_SET)) {
                BUFFERED_OUTPUT(output, " <br /> ", 8);
           }
            STATE_CLR(ansi_state, STATE_QUOTE_LINE);
            STATE_SET(ansi_state, STATE_NEW_LINE);
        } else {
            if (STATE_ISSET(ansi_state, STATE_ESC_SET)) {
                if (buf[i] == 'm') {
                    /*
                     *[0;1;4;31m */
                    if (STATE_ISSET(ansi_state, STATE_FONT_SET)) {
                        BUFFERED_OUTPUT(output, "</font>", 7);
                        STATE_CLR(ansi_state, STATE_FONT_SET);
                    }
                    if (i < buflen - 1) {
                        generate_font_style(&font_style, ansi_val, ival + 1);
                        if (STATE_ISSET(ansi_state, STATE_QUOTE_LINE))
                            STYLE_SET(font_style, FONT_STYLE_QUOTE);
                        print_font_style(font_style, output);
                        STATE_SET(ansi_state, STATE_FONT_SET);
                        STATE_CLR(ansi_state, STATE_ESC_SET);
                        /*
                         * STYLE_ZERO(font_style);
                         */
                        /*
                         * clear ansi_val[] array
                         */
                        bzero(ansi_val, sizeof(ansi_val));
                        ival = 0;
                    }
                } else if (isalpha(buf[i])) {
                    /*
                     *[23;32H */
                    /*
                     * ignore it
                     */
                    STATE_CLR(ansi_state, STATE_ESC_SET);
                    STYLE_ZERO(font_style);
                    /*
                     * clear ansi_val[] array
                     */
                    bzero(ansi_val, sizeof(ansi_val));
                    ival = 0;
                    continue;
                } else if (buf[i] == ';') {
                    if (ival < sizeof(ansi_val) - 1) {
                        ival++; /* go to next ansi_val[] element */
                        ansi_val[ival] = 0;
                    }
                } else if (buf[i] >= '0' && buf[i] <= '9') {
                    ansi_val[ival] *= 10;
                    ansi_val[ival] += (buf[i] - '0');
                } else {
                    /*
                     *[1;32/XXXX or *[* or *[[ */
                    /*
                     * not a valid ANSI string, just output it
                     */
                    size_t len;

                    ansi_end = &buf[i];
                    len = ansi_end - ansi_begin + 1;
                    print_raw_ansi(ansi_begin, len, output);
                    STATE_CLR(ansi_state, STATE_ESC_SET);
                    /*
                     * clear ansi_val[] array
                     */
                    bzero(ansi_val, sizeof(ansi_val));
                    ival = 0;
                }

            } else
                print_raw_ansi(&buf[i], 1, output);
        }
    }
    if (STATE_ISSET(ansi_state, STATE_FONT_SET)) {
        BUFFERED_OUTPUT(output, "</font>", 7);
        STATE_CLR(ansi_state, STATE_FONT_SET);
    }

    if (att) { //attachment
        char *cur_ptr, *attachfilename, *attachptr;
        long attach_len, attach_pos, newlen;
        off_t ptrlen;
        zval *item;

        cur_ptr = buf + i;
        ptrlen = article_len - i;
        while (ptrlen > 0) {
            if (((attachfilename = checkattach(cur_ptr, ptrlen,
                                               &attach_len, &attachptr)) == NULL)) {
                break;
            }
            attach_pos = attachfilename - buf;
            newlen = attachptr - cur_ptr + attach_len;
            cur_ptr += newlen;
            ptrlen -= newlen;
            if (ptrlen < 0) break;
            MAKE_STD_ZVAL(item);
            array_init(item);
            add_assoc_string(item, "name", attachfilename, 1);
            add_assoc_long(item, "size", attach_len);
            add_assoc_long(item, "pos", attach_pos);
            add_next_index_zval(attachment, item);
        }
    }
    BUFFERED_FLUSH(output);

}