static int create_text(int fd, unsigned char **text) { size_t len = 0, buf_size = 16, rx; unsigned char *pend_seq = TEXT_END_SEQ; unsigned char *buf; buf_size = resize_buf(text, buf_size); while(buf_size) { buf = *text; if (receive(fd, &buf[len], 1, &rx) != 0 || rx == 0) goto bad_text; if (buf[len] == *pend_seq) { if (*++pend_seq == '\0') break; } else { pend_seq = TEXT_END_SEQ; } if (++len == buf_size) buf_size = resize_buf(text, buf_size); } if(len < 3 || !buf_size) goto bad_text; (*text)[len - 2] = '\0'; return len - 2; bad_text: if (buf_size) free(*text); *text = NULL; return 0; }
TwsXml::TwsXml() : file(NULL), buf_size(0), buf_len(0), buf(NULL), curDoc(NULL), curNode(NULL) { resize_buf(); }
/* * alloc_node() * Allocate a new node * * Somewhat complicated because the file's storage structure is stored * at the front of the file. We read in the first sector, then extend * the buffered block out to the indicated size. */ static struct openfile * alloc_node(daddr_t d) { struct buf *b; struct fs_file *fs; ulong len, fslen; struct openfile *o; /* * Get buf, address first sector as an fs_file */ b = find_buf(d, 1, ABC_FILL); fs = index_buf(b, 0, 1); ASSERT(fs->fs_nblk > 0, "alloc_node: zero"); ASSERT(fs->fs_blks[0].a_start == d, "alloc_node: mismatch"); /* * Extend the buf if necessary */ len = fs->fs_blks[0].a_len; fslen = fs->fs_len; if (len > 1) { if (len > EXTSIZ) { len = EXTSIZ; } if (resize_buf(d, (uint)len, 1)) { return(0); } } /* * Create a new openfile and return it */ o = malloc(sizeof(struct openfile)); if (o == 0) { return(0); } o->o_file = d; o->o_len = len; o->o_hiwrite = fslen; o->o_refs = 1; o->o_flags = 0; return(o); }
xmlDocPtr TwsXml::nextXmlDoc() { xmlDocPtr doc = NULL; if( file == NULL ) { return doc; } /* This is ugly code. If we will rewrite it to use xml push parser then we could avoid resize_buf(), memmove() and even find_form_feed(). */ int jump_ff = 0; char *cp = buf; int tmp_len = buf_len; while( true ) { int ff = find_form_feed(cp, tmp_len); if( ff < tmp_len ) { cp += ff; jump_ff = 1; break; } cp += tmp_len; if( (buf_len + CHUNK_SIZE) >= buf_size ) { resize_buf(); cp = buf + buf_len; } tmp_len = fread(cp, 1, CHUNK_SIZE, (FILE*)file); if( tmp_len <=0 ) { jump_ff = 0; break; } buf_len += tmp_len; } doc = xmlReadMemory( buf, cp-buf, "URL", NULL, 0 ); buf_len -= cp - buf + jump_ff; memmove( buf, cp + jump_ff, buf_len ); return doc; }
static int read_whole_file(struct mparse *curp, const char *file, int fd, struct buf *fb, int *with_mmap) { gzFile gz; size_t off; ssize_t ssz; #if HAVE_MMAP struct stat st; if (fstat(fd, &st) == -1) err((int)MANDOCLEVEL_SYSERR, "%s", file); /* * If we're a regular file, try just reading in the whole entry * via mmap(). This is faster than reading it into blocks, and * since each file is only a few bytes to begin with, I'm not * concerned that this is going to tank any machines. */ if (curp->gzip == 0 && S_ISREG(st.st_mode)) { if (st.st_size > 0x7fffffff) { mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL); return 0; } *with_mmap = 1; fb->sz = (size_t)st.st_size; fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) return 1; } #endif if (curp->gzip) { if ((gz = gzdopen(fd, "rb")) == NULL) err((int)MANDOCLEVEL_SYSERR, "%s", file); } else gz = NULL; /* * If this isn't a regular file (like, say, stdin), then we must * go the old way and just read things in bit by bit. */ *with_mmap = 0; off = 0; fb->sz = 0; fb->buf = NULL; for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL); break; } resize_buf(fb, 65536); } ssz = curp->gzip ? gzread(gz, fb->buf + (int)off, fb->sz - off) : read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; return 1; } if (ssz == -1) err((int)MANDOCLEVEL_SYSERR, "%s", file); off += (size_t)ssz; } free(fb->buf); fb->buf = NULL; return 0; }
/* * Main parse routine for a buffer. * It assumes encoding and line numbering are already set up. * It can recurse directly (for invocations of user-defined * macros, inline equations, and input line traps) * and indirectly (for .so file inclusion). */ static void mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start) { const struct tbl_span *span; struct buf ln; const char *save_file; char *cp; size_t pos; /* byte number in the ln buffer */ enum rofferr rr; int of; int lnn; /* line number in the real file */ int fd; unsigned char c; memset(&ln, 0, sizeof(ln)); lnn = curp->line; pos = 0; while (i < blk.sz) { if (0 == pos && '\0' == blk.buf[i]) break; if (start) { curp->line = lnn; curp->reparse_count = 0; if (lnn < 3 && curp->filenc & MPARSE_UTF8 && curp->filenc & MPARSE_LATIN1) curp->filenc = preconv_cue(&blk, i); } while (i < blk.sz && (start || blk.buf[i] != '\0')) { /* * When finding an unescaped newline character, * leave the character loop to process the line. * Skip a preceding carriage return, if any. */ if ('\r' == blk.buf[i] && i + 1 < blk.sz && '\n' == blk.buf[i + 1]) ++i; if ('\n' == blk.buf[i]) { ++i; ++lnn; break; } /* * Make sure we have space for the worst * case of 11 bytes: "\\[u10ffff]\0" */ if (pos + 11 > ln.sz) resize_buf(&ln, 256); /* * Encode 8-bit input. */ c = blk.buf[i]; if (c & 0x80) { if ( ! (curp->filenc && preconv_encode( &blk, &i, &ln, &pos, &curp->filenc))) { mandoc_vmsg(MANDOCERR_CHAR_BAD, curp, curp->line, pos, "0x%x", c); ln.buf[pos++] = '?'; i++; } continue; } /* * Exclude control characters. */ if (c == 0x7f || (c < 0x20 && c != 0x09)) { mandoc_vmsg(c == 0x00 || c == 0x04 || c > 0x0a ? MANDOCERR_CHAR_BAD : MANDOCERR_CHAR_UNSUPP, curp, curp->line, pos, "0x%x", c); i++; if (c != '\r') ln.buf[pos++] = '?'; continue; } /* Trailing backslash = a plain char. */ if (blk.buf[i] != '\\' || i + 1 == blk.sz) { ln.buf[pos++] = blk.buf[i++]; continue; } /* * Found escape and at least one other character. * When it's a newline character, skip it. * When there is a carriage return in between, * skip that one as well. */ if ('\r' == blk.buf[i + 1] && i + 2 < blk.sz && '\n' == blk.buf[i + 2]) ++i; if ('\n' == blk.buf[i + 1]) { i += 2; ++lnn; continue; } if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { i += 2; /* Comment, skip to end of line */ for (; i < blk.sz; ++i) { if ('\n' == blk.buf[i]) { ++i; ++lnn; break; } } /* Backout trailing whitespaces */ for (; pos > 0; --pos) { if (ln.buf[pos - 1] != ' ') break; if (pos > 2 && ln.buf[pos - 2] == '\\') break; } break; } /* Catch escaped bogus characters. */ c = (unsigned char) blk.buf[i+1]; if ( ! (isascii(c) && (isgraph(c) || isblank(c)))) { mandoc_vmsg(MANDOCERR_CHAR_BAD, curp, curp->line, pos, "0x%x", c); i += 2; ln.buf[pos++] = '?'; continue; } /* Some other escape sequence, copy & cont. */ ln.buf[pos++] = blk.buf[i++]; ln.buf[pos++] = blk.buf[i++]; } if (pos >= ln.sz) resize_buf(&ln, 256); ln.buf[pos] = '\0'; /* * A significant amount of complexity is contained by * the roff preprocessor. It's line-oriented but can be * expressed on one line, so we need at times to * readjust our starting point and re-run it. The roff * preprocessor can also readjust the buffers with new * data, so we pass them in wholesale. */ of = 0; /* * Maintain a lookaside buffer of all parsed lines. We * only do this if mparse_keep() has been invoked (the * buffer may be accessed with mparse_getkeep()). */ if (curp->secondary) { curp->secondary->buf = mandoc_realloc( curp->secondary->buf, curp->secondary->sz + pos + 2); memcpy(curp->secondary->buf + curp->secondary->sz, ln.buf, pos); curp->secondary->sz += pos; curp->secondary->buf [curp->secondary->sz] = '\n'; curp->secondary->sz++; curp->secondary->buf [curp->secondary->sz] = '\0'; } rerun: rr = roff_parseln(curp->roff, curp->line, &ln, &of); switch (rr) { case ROFF_REPARSE: if (REPARSE_LIMIT >= ++curp->reparse_count) mparse_buf_r(curp, ln, of, 0); else mandoc_msg(MANDOCERR_ROFFLOOP, curp, curp->line, pos, NULL); pos = 0; continue; case ROFF_APPEND: pos = strlen(ln.buf); continue; case ROFF_RERUN: goto rerun; case ROFF_IGN: pos = 0; continue; case ROFF_SO: if ( ! (curp->options & MPARSE_SO) && (i >= blk.sz || blk.buf[i] == '\0')) { curp->sodest = mandoc_strdup(ln.buf + of); free(ln.buf); return; } /* * We remove `so' clauses from our lookaside * buffer because we're going to descend into * the file recursively. */ if (curp->secondary) curp->secondary->sz -= pos + 1; save_file = curp->file; if ((fd = mparse_open(curp, ln.buf + of)) != -1) { mparse_readfd(curp, fd, ln.buf + of); close(fd); curp->file = save_file; } else { curp->file = save_file; mandoc_vmsg(MANDOCERR_SO_FAIL, curp, curp->line, pos, ".so %s", ln.buf + of); ln.sz = mandoc_asprintf(&cp, ".sp\nSee the file %s.\n.sp", ln.buf + of); free(ln.buf); ln.buf = cp; of = 0; mparse_buf_r(curp, ln, of, 0); } pos = 0; continue; default: break; } /* * If input parsers have not been allocated, do so now. * We keep these instanced between parsers, but set them * locally per parse routine since we can use different * parsers with each one. */ if (curp->man == NULL || curp->man->macroset == MACROSET_NONE) choose_parser(curp); /* * Lastly, push down into the parsers themselves. * If libroff returns ROFF_TBL, then add it to the * currently open parse. Since we only get here if * there does exist data (see tbl_data.c), we're * guaranteed that something's been allocated. * Do the same for ROFF_EQN. */ if (rr == ROFF_TBL) while ((span = roff_span(curp->roff)) != NULL) roff_addtbl(curp->man, span); else if (rr == ROFF_EQN) roff_addeqn(curp->man, roff_eqn(curp->roff)); else if ((curp->man->macroset == MACROSET_MDOC ? mdoc_parseln(curp->man, curp->line, ln.buf, of) : man_parseln(curp->man, curp->line, ln.buf, of)) == 2) break; /* Temporary buffers typically are not full. */ if (0 == start && '\0' == blk.buf[i]) break; /* Start the next input line. */ pos = 0; } free(ln.buf); }
static int read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) { struct stat st; size_t off; ssize_t ssz; if (-1 == fstat(fd, &st)) { perror(file); return(0); } /* * If we're a regular file, try just reading in the whole entry * via mmap(). This is faster than reading it into blocks, and * since each file is only a few bytes to begin with, I'm not * concerned that this is going to tank any machines. */ if (S_ISREG(st.st_mode)) { if (st.st_size >= (1U << 31)) { fprintf(stderr, "%s: input too large\n", file); return(0); } *with_mmap = 1; fb->sz = (size_t)st.st_size; fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) return(1); } /* * If this isn't a regular file (like, say, stdin), then we must * go the old way and just read things in bit by bit. */ *with_mmap = 0; off = 0; fb->sz = 0; fb->buf = NULL; for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { fprintf(stderr, "%s: input too large\n", file); break; } resize_buf(fb, 65536); } ssz = read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; return(1); } if (ssz == -1) { perror(file); break; } off += (size_t)ssz; } free(fb->buf); fb->buf = NULL; return(0); }
/* * Main parse routine for an opened file. This is called for each * opened file and simply loops around the full input file, possibly * nesting (i.e., with `so'). */ static void mparse_buf_r(struct mparse *curp, struct buf blk, int start) { const struct tbl_span *span; struct buf ln; enum rofferr rr; int i, of, rc; int pos; /* byte number in the ln buffer */ int lnn; /* line number in the real file */ unsigned char c; memset(&ln, 0, sizeof(struct buf)); lnn = curp->line; pos = 0; for (i = 0; i < (int)blk.sz; ) { if (0 == pos && '\0' == blk.buf[i]) break; if (start) { curp->line = lnn; curp->reparse_count = 0; } while (i < (int)blk.sz && (start || '\0' != blk.buf[i])) { /* * When finding an unescaped newline character, * leave the character loop to process the line. * Skip a preceding carriage return, if any. */ if ('\r' == blk.buf[i] && i + 1 < (int)blk.sz && '\n' == blk.buf[i + 1]) ++i; if ('\n' == blk.buf[i]) { ++i; ++lnn; break; } /* * Warn about bogus characters. If you're using * non-ASCII encoding, you're screwing your * readers. Since I'd rather this not happen, * I'll be helpful and drop these characters so * we don't display gibberish. Note to manual * writers: use special characters. */ c = (unsigned char) blk.buf[i]; if ( ! (isascii(c) && (isgraph(c) || isblank(c)))) { mandoc_msg(MANDOCERR_BADCHAR, curp, curp->line, pos, "ignoring byte"); i++; continue; } /* Trailing backslash = a plain char. */ if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) { if (pos >= (int)ln.sz) resize_buf(&ln, 256); ln.buf[pos++] = blk.buf[i++]; continue; } /* * Found escape and at least one other character. * When it's a newline character, skip it. * When there is a carriage return in between, * skip that one as well. */ if ('\r' == blk.buf[i + 1] && i + 2 < (int)blk.sz && '\n' == blk.buf[i + 2]) ++i; if ('\n' == blk.buf[i + 1]) { i += 2; ++lnn; continue; } if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) { i += 2; /* Comment, skip to end of line */ for (; i < (int)blk.sz; ++i) { if ('\n' == blk.buf[i]) { ++i; ++lnn; break; } } /* Backout trailing whitespaces */ for (; pos > 0; --pos) { if (ln.buf[pos - 1] != ' ') break; if (pos > 2 && ln.buf[pos - 2] == '\\') break; } break; } /* Some other escape sequence, copy & cont. */ if (pos + 1 >= (int)ln.sz) resize_buf(&ln, 256); ln.buf[pos++] = blk.buf[i++]; ln.buf[pos++] = blk.buf[i++]; } if (pos >= (int)ln.sz) resize_buf(&ln, 256); ln.buf[pos] = '\0'; /* * A significant amount of complexity is contained by * the roff preprocessor. It's line-oriented but can be * expressed on one line, so we need at times to * readjust our starting point and re-run it. The roff * preprocessor can also readjust the buffers with new * data, so we pass them in wholesale. */ of = 0; /* * Maintain a lookaside buffer of all parsed lines. We * only do this if mparse_keep() has been invoked (the * buffer may be accessed with mparse_getkeep()). */ if (curp->secondary) { curp->secondary->buf = mandoc_realloc (curp->secondary->buf, curp->secondary->sz + pos + 2); memcpy(curp->secondary->buf + curp->secondary->sz, ln.buf, pos); curp->secondary->sz += pos; curp->secondary->buf [curp->secondary->sz] = '\n'; curp->secondary->sz++; curp->secondary->buf [curp->secondary->sz] = '\0'; } rerun: rr = roff_parseln (curp->roff, curp->line, &ln.buf, &ln.sz, of, &of); switch (rr) { case (ROFF_REPARSE): if (REPARSE_LIMIT >= ++curp->reparse_count) mparse_buf_r(curp, ln, 0); else mandoc_msg(MANDOCERR_ROFFLOOP, curp, curp->line, pos, NULL); pos = 0; continue; case (ROFF_APPEND): pos = (int)strlen(ln.buf); continue; case (ROFF_RERUN): goto rerun; case (ROFF_IGN): pos = 0; continue; case (ROFF_ERR): assert(MANDOCLEVEL_FATAL <= curp->file_status); break; case (ROFF_SO): /* * We remove `so' clauses from our lookaside * buffer because we're going to descend into * the file recursively. */ if (curp->secondary) curp->secondary->sz -= pos + 1; mparse_readfd_r(curp, -1, ln.buf + of, 1); if (MANDOCLEVEL_FATAL <= curp->file_status) break; pos = 0; continue; default: break; } /* * If we encounter errors in the recursive parse, make * sure we don't continue parsing. */ if (MANDOCLEVEL_FATAL <= curp->file_status) break; /* * If input parsers have not been allocated, do so now. * We keep these instanced between parsers, but set them * locally per parse routine since we can use different * parsers with each one. */ if ( ! (curp->man || curp->mdoc)) pset(ln.buf + of, pos - of, curp); /* * Lastly, push down into the parsers themselves. One * of these will have already been set in the pset() * routine. * If libroff returns ROFF_TBL, then add it to the * currently open parse. Since we only get here if * there does exist data (see tbl_data.c), we're * guaranteed that something's been allocated. * Do the same for ROFF_EQN. */ rc = -1; if (ROFF_TBL == rr) while (NULL != (span = roff_span(curp->roff))) { rc = curp->man ? man_addspan(curp->man, span) : mdoc_addspan(curp->mdoc, span); if (0 == rc) break; } else if (ROFF_EQN == rr) rc = curp->mdoc ? mdoc_addeqn(curp->mdoc, roff_eqn(curp->roff)) : man_addeqn(curp->man, roff_eqn(curp->roff)); else if (curp->man || curp->mdoc) rc = curp->man ? man_parseln(curp->man, curp->line, ln.buf, of) : mdoc_parseln(curp->mdoc, curp->line, ln.buf, of); if (0 == rc) { assert(MANDOCLEVEL_FATAL <= curp->file_status); break; } /* Temporary buffers typically are not full. */ if (0 == start && '\0' == blk.buf[i]) break; /* Start the next input line. */ pos = 0; } free(ln.buf); }
static void buf_add_str(ErlNifEnv* env, int buf_len, struct buf *rbuf, char *data, int len) { resize_buf(env, buf_len, rbuf, len); memcpy(rbuf->b + rbuf->len, data, len); rbuf->len += len; }
static void buf_add_char(ErlNifEnv* env, int buf_len, struct buf *rbuf, unsigned char c) { resize_buf(env, buf_len, rbuf, 1); (rbuf->b)[rbuf->len] = c; rbuf->len += 1; }
void speed() { int keyboard = _open("/dev/keyboard", 0, 0); int stdin = _open("/dev/stdin", 0, 0); char ch; int fd = _open(active_proc->name, 0, 0); int size = _seek(fd, 0, SEEK_END); size++; //terminating '\0' _seek(fd, 0, SEEK_SET); char* str = _malloc(size); bzero(str, size); _read(fd, str, size); line *startline = _malloc(sizeof(line)); startline->num_chars=0; startline->offset=0; startline->next = NULL; startline->prev = NULL; line * actualline = startline; int pos = 0; while (str[pos]!='\0') { _printf("%c", str[pos]); if(str[pos] == '\n' || str[pos] == '\t') { NEXT_LINE } else { actualline->num_chars++; } pos++; if(pos == size - 1) { //terminating \0 size*=2; str = resize_buf(size, str); } } _close(fd); //flush stdin while (_read(stdin, &ch, sizeof(ch)) != 0) ; while (!keydown(ESCAPE, keyboard)) { if(pos == size - 1) { //terminating \0 size *= 2; str = resize_buf(size, str); } ch = _fgetch(stdin); switch(ch){ case '\a': break; case '\b': if(actualline == startline && startline->num_chars == 0) { //nothing to erase break; } if(str[pos - 1]=='\n' || str[pos - 1]=='\t') { //erase '\n' or '\t' PREV_LINE } else { //erase 1 character actualline->num_chars--; _printf("%c", ch); } str[--pos] = '\0'; if (pos == size / 4 - 1) { size /= 2; str = resize_buf(size, str); } break; default: _printf("%c", ch); str[pos] = ch; if(ch == '\n' || ch == '\t') { NEXT_LINE } else { actualline->num_chars++; } pos++; } } //flush stdin while (_read(stdin, &ch, sizeof(ch)) != 0) ; //DUMP_LINES _unlink(active_proc->name); // fd = _open(active_proc->name, 0, 0); // int fsize = _seek(fd, 0, SEEK_END); // _close(fd); // fd = _open(active_proc->name, 0, 0); // char* nullstring = _malloc(fsize); // bzero(nullstring, fsize); // _free(nullstring); // _write(fd, nullstring, fsize); // _close(fd); fd = _open(active_proc->name, O_CREAT, 0); _write(fd, str, strlen(str)); for(line *temp = startline; temp != NULL; temp = temp->next) { _free(temp); } _free(str); _close(keyboard); _close(stdin); _close(fd); _exit(0); }
static int read_whole_file(struct mparse *curp, const char *file, int fd, struct buf *fb, int *with_mmap) { size_t off; ssize_t ssz; #ifdef HAVE_MMAP struct stat st; if (-1 == fstat(fd, &st)) { curp->file_status = MANDOCLEVEL_SYSERR; if (curp->mmsg) (*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status, file, 0, 0, strerror(errno)); return(0); } /* * If we're a regular file, try just reading in the whole entry * via mmap(). This is faster than reading it into blocks, and * since each file is only a few bytes to begin with, I'm not * concerned that this is going to tank any machines. */ if (S_ISREG(st.st_mode)) { if (st.st_size >= (1U << 31)) { curp->file_status = MANDOCLEVEL_FATAL; if (curp->mmsg) (*curp->mmsg)(MANDOCERR_TOOLARGE, curp->file_status, file, 0, 0, NULL); return(0); } *with_mmap = 1; fb->sz = (size_t)st.st_size; fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0); if (fb->buf != MAP_FAILED) return(1); } #endif /* * If this isn't a regular file (like, say, stdin), then we must * go the old way and just read things in bit by bit. */ *with_mmap = 0; off = 0; fb->sz = 0; fb->buf = NULL; for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { curp->file_status = MANDOCLEVEL_FATAL; if (curp->mmsg) (*curp->mmsg)(MANDOCERR_TOOLARGE, curp->file_status, file, 0, 0, NULL); break; } resize_buf(fb, 65536); } ssz = read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; return(1); } if (ssz == -1) { curp->file_status = MANDOCLEVEL_SYSERR; if (curp->mmsg) (*curp->mmsg)(MANDOCERR_SYSREAD, curp->file_status, file, 0, 0, strerror(errno)); break; } off += (size_t)ssz; } free(fb->buf); fb->buf = NULL; return(0); }