/* * _peek: * @self: A valid %GSDLTokenizer. * @result: (out): The location to store the resulting %gunichar. * @err: (out) (allow-none): Location to store any %GError, or %NULL. * * Looks at the next UTF-8 character from the input. Will return %EOF at the end of the input. * * Returns: Whether the peek succeeded. This should always be checked, as _peek() may or may not * have to read from the input. */ static bool _peek(GSDLTokenizer *self, gunichar *result, GError **err) { if (!self->peek_avail) { if (self->stringbuf) { if (*self->stringbuf) { self->peeked = *(self->stringbuf++); } else { self->stringbuf = NULL; self->peeked = EOF; } self->peek_avail = true; } else { if (self->channel == NULL) return false; switch (g_io_channel_read_unichar(self->channel, &(self->peeked), err)) { case G_IO_STATUS_ERROR: self->channel = NULL; self->peek_avail = false; return false; case G_IO_STATUS_EOF: self->peeked = EOF; g_io_channel_shutdown(self->channel, FALSE, NULL); g_io_channel_unref(self->channel); self->channel = NULL; case G_IO_STATUS_AGAIN: case G_IO_STATUS_NORMAL: default: self->peek_avail = true; } } } *result = self->peeked; return true; }
static VALUE rg_readchar(VALUE self) { gunichar thechar; GError* err = NULL; GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); ioc_error(status, err); return UINT2NUM(thechar); }
static VALUE rg_getc(VALUE self) { gunichar thechar; GError* err = NULL; VALUE ret; GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); if (status == G_IO_STATUS_EOF){ ret = Qnil; } else { ioc_error(status, err); ret = UINT2NUM(thechar); } return ret; }
/* * _read: * @self: A valid %GSDLTokenizer. * @result: (out): The location to store the resulting %gunichar. * @err: (out) (allow-none): Location to store any %GError, or %NULL. * * Reads a single UTF-8 character from the input. Will return %EOF once at the end of the input. * * Returns: Whether the read succeeded. */ static bool _read(GSDLTokenizer *self, gunichar *result, GError **err) { if (self->peek_avail) { *result = self->peeked; self->peek_avail = false; } else if (self->stringbuf) { if (!*self->stringbuf) { self->stringbuf = NULL; *result = EOF; } else { *result = *(self->stringbuf++); } return true; } else { if (G_UNLIKELY(!self->channel)) return false; switch (g_io_channel_read_unichar(self->channel, result, err)) { case G_IO_STATUS_ERROR: self->channel = NULL; self->peek_avail = false; return false; case G_IO_STATUS_EOF: self->peek_avail = false; *result = EOF; g_io_channel_shutdown(self->channel, FALSE, NULL); g_io_channel_unref(self->channel); self->channel = NULL; return true; case G_IO_STATUS_AGAIN: case G_IO_STATUS_NORMAL: break; } } if (*result == '\n') { self->line++; self->col = 1; } else { self->col++; } return true; }
static VALUE rg_each_char(VALUE self) { if (!rb_block_given_p()) { rb_raise(rb_eArgError, "called without a block"); } while (TRUE){ gunichar thechar; GError* err = NULL; GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); if (status == G_IO_STATUS_EOF){ break; } else { ioc_error(status, err); rb_yield(UINT2NUM(thechar)); } } return self; }
int main (int argc, char **argv) { enum ParserState state = 0; gunichar in; gboolean init = FALSE; /* used to parse attribute */ gint attributes = 0; /* Input/output */ FILE *input = stdin; FILE *output = stdout; /* Error */ GError *error = NULL; /* init the glib system */ g_type_init(); /* needed to get the right charset from g_get_charset */ setlocale(LC_ALL, ""); /* Get charset */ g_get_charset(&input_charset); /* parse options */ parse_cmd_options(&argc, &argv); /* Handle input file */ if(input_file && strcmp(input_file, "-")) { input = g_fopen(input_file, "r"); EXCEPTION(input == NULL, "Failed to open: %s: %s\n", input_file, strerror(errno)); } /* Handle output file */ if(output_file) { output = g_fopen(output_file, "w"); EXCEPTION(output == NULL, "Failed to open: %s: %s\n", output_file, strerror(errno)); } /* Create channel for input */ GIOChannel *chan = g_io_channel_unix_new(fileno(input)); /* Set channel encoding */ g_io_channel_set_encoding(chan, input_charset,&error); EXCEPTION(error != NULL, "Failed to set input encoding: %s\n", error->message); /* Read input */ while(g_io_channel_read_unichar(chan, &in, &error) == G_IO_STATUS_NORMAL && error == NULL) { if(!init) { /* Output html header */ print_page_header(output); /* Convert and print body */ fprintf(output, "<pre style='font-family:monospace'>\n"); init = TRUE; } /* If we hit the escape character, go into 'attribute parsing' mode */ if(in == ESCAPE_CHAR) { state = PARSE_ATTRIBUTE; /* reset */ attributes = 0; } /* if we are in attribute parsing mode, parse attribute */ else if(state == PARSE_ATTRIBUTE) { if(in == '[') { /* Begin of attributes */ state = PARSE_COLOR_ATTRIBUTE; }else { WARNING("Unknown Escape sequence found: %i\n", in); state = PARSE_NORMAL; } } else if(state == PARSE_COLOR_ATTRIBUTE) { if (in == ';') { /* End of element */ process_attribute(output, attributes); attributes = 0; } else if(in == 'm') { /* end of attribute */ process_attribute(output, attributes); state = PARSE_NORMAL; } else if(in >= '0' && in <= '9') { attributes *= 10; attributes += in-'0'; }else if (in == 'h' || in == 'l' ) { WARNING("Unsupported attribute found: %i\n", in); state = PARSE_NORMAL; } continue; } else if (state == PARSE_NORMAL) { /* special chars (htmlspecialchars php doc) */ if(in == '"') fputs(""", output); else if(in == '\'') fputs("'", output); else if(in == '&') fputs("&", output); else if(in == '<') fputs("<", output); else if(in == '>') fputs(">", output); /* ascii values stay ascii*/ else if(in >= 0 && in <= 177) fprintf(output, "%c", (char)in); /* Rest we encode in utf8 */ else fprintf(output, "&#%i;", in); } } EXCEPTION(error != NULL, "Failed to read input character: %s\n", error->message); if(init) { /* Close open tags */ process_attribute(output, 0); fprintf(output,"\n </pre>\n"); print_page_footer(output); } /* free input channel */ g_io_channel_unref(chan); /* close i/o */ if(input != stdin) fclose(input); if(output != stdout) fclose(output); return EXIT_SUCCESS; }