Exemplo n.º 1
0
Arquivo: zmisc.c Projeto: hackqiang/gs
/* <string> getenv false */
static int
zgetenv(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    char *str;
    byte *value;
    int len = 0;

    check_read_type(*op, t_string);
    str = ref_to_string(op, imemory, "getenv key");
    if (str == 0)
        return_error(e_VMerror);
    if (gp_getenv(str, (char *)0, &len) > 0) {	/* key missing */
        ifree_string((byte *) str, r_size(op) + 1, "getenv key");
        make_false(op);
        return 0;
    }
    value = ialloc_string(len, "getenv value");
    if (value == 0) {
        ifree_string((byte *) str, r_size(op) + 1, "getenv key");
        return_error(e_VMerror);
    }
    DISCARD(gp_getenv(str, (char *)value, &len));	/* can't fail */
    ifree_string((byte *) str, r_size(op) + 1, "getenv key");
    /* Delete the stupid C string terminator. */
    value = iresize_string(value, len, len - 1,
                           "getenv value");	/* can't fail */
    push(1);
    make_string(op - 1, a_all | icurrent_space, len - 1, value);
    make_true(op);
    return 0;
}
Exemplo n.º 2
0
ENUM_PTRS_END

static RELOC_PTRS_WITH(TExecution_Context_reloc_ptrs, TExecution_Context *mptr)
{
    RELOC_PTR(TExecution_Context, current_face);
    /* RELOC_PTR(TExecution_Context, code);  // local, no gc invocations */
    RELOC_PTR(TExecution_Context, FDefs);
    RELOC_PTR(TExecution_Context, IDefs);
    /* RELOC_PTR(TExecution_Context, glyphIns);  // Never used. */
    RELOC_PTR(TExecution_Context, callStack);
    RELOC_PTR(TExecution_Context, codeRangeTable[0].Base);
    RELOC_PTR(TExecution_Context, codeRangeTable[1].Base);
    RELOC_PTR(TExecution_Context, codeRangeTable[2].Base);
    RELOC_PTR(TExecution_Context, storage);
    RELOC_PTR(TExecution_Context, stack);
    /* zp0, // local, no gc invocations */
    /* zp1, // local, no gc invocations */
    /* zp2, // local, no gc invocations */
    RELOC_PTR(TExecution_Context, pts.org_x);
    RELOC_PTR(TExecution_Context, pts.org_y);
    RELOC_PTR(TExecution_Context, pts.cur_x);
    RELOC_PTR(TExecution_Context, pts.cur_y);
    RELOC_PTR(TExecution_Context, pts.touch);
    RELOC_PTR(TExecution_Context, pts.contours);
    RELOC_PTR(TExecution_Context, twilight.org_x);
    RELOC_PTR(TExecution_Context, twilight.org_y);
    RELOC_PTR(TExecution_Context, twilight.cur_x);
    RELOC_PTR(TExecution_Context, twilight.cur_y);
    RELOC_PTR(TExecution_Context, twilight.touch);
    RELOC_PTR(TExecution_Context, twilight.contours);
    RELOC_PTR(TExecution_Context, cvt);
    RELOC_PTR(TExecution_Context, memory);
    DISCARD(mptr);
}
Exemplo n.º 3
0
Arquivo: zmisc.c Projeto: hackqiang/gs
/* - .defaultpapersize false */
static int
zdefaultpapersize(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    byte *value;
    int len = 0;

    if (gp_defaultpapersize((char *)0, &len) > 0) {
        /* no default paper size */
        push(1);
        make_false(op);
        return 0;
    }

    value = ialloc_string(len, "defaultpapersize value");
    if (value == 0) {
        return_error(e_VMerror);
    }
    DISCARD(gp_defaultpapersize((char *)value, &len));	/* can't fail */
    /* Delete the stupid C string terminator. */
    value = iresize_string(value, len, len - 1,
                           "defaultpapersize value");	/* can't fail */
    push(2);
    make_string(op - 1, a_all | icurrent_space, len - 1, value);
    make_true(op);
    return 0;
}
Exemplo n.º 4
0
bp_Caption * bp_parseCaption(bp_Context * context, xmlNodePtr node) {
	bp_Caption * result = malloc(sizeof(bp_Caption));
	xmlAttrPtr attr;
	xmlNodePtr child;

	bp_initNode(&result->node, BPE_CAPTION);
	result->inlineAttr = *(context->inlineAttr);

	for (attr = node->properties; attr; attr = attr->next) {
		bp_parseInlineAttribute(context, &result->inlineAttr, attr);
	}

	child = node->children;
	if (ELEM(child) == BPE_TEXT) {
		int len;

		len = strlen(child->content);
		result->text = malloc(++len);
		memcpy(result->text, child->children, len);
	} else {
		DISCARD(child);
	}
	
	return result;
}
Exemplo n.º 5
0
/* Wrapper procedure called to start the new thread. */
static void *
gp_thread_begin_wrapper(void *thread_data /* gp_thread_creation_closure_t * */)
{
    gp_thread_creation_closure_t closure;

    closure = *(gp_thread_creation_closure_t *)thread_data;
    free(thread_data);
    DISCARD(closure.proc(closure.proc_data));
    return NULL;		/* return value is ignored */
}
Exemplo n.º 6
0
static
ENUM_PTRS_WITH(gx_ttfReader_enum_ptrs, gx_ttfReader *mptr)
    {
        /* The fields 'pfont' and 'glyph_data' may contain pointers from global
           to local memory ( see a comment in gxttfb.h).
           They must be NULL when a garbager is invoked.
           Due to that we don't enumerate and don't relocate them.
         */
        DISCARD(mptr);
        return 0;
    }
Exemplo n.º 7
0
void bp_parseInlineContent(bp_Context * context, bp_Node * const parent, xmlNodePtr node) {
	xmlNodePtr child;

	for (child = node->children; child; child = child->next) {
		switch (ELEM(child)) {
			case BPE_TEXT:
				ADD(bp_parseText(context, child));
				break;
			case BPE_INLINE:
				ADD(bp_parseInline(context, child));
				break;
			case BPE_LABEL:
				ADD(bp_parseLabel(context, child));
				break;
			case BPE_REF:
				ADD(bp_parseRef(context, child));
				break;
			default: 
				DISCARD(child);
		}
	}
}
Exemplo n.º 8
0
/* Write one code map. */
static int
cmap_put_code_map(const gs_memory_t *mem,
		  stream *s, int which, const gs_cmap_t *pcmap,
		  const cmap_operators_t *pcmo,
		  psf_put_name_chars_proc_t put_name_chars, 
		  int font_index_only)
{
    /* For simplicity, produce one entry for each lookup range. */
    gs_cmap_lookups_enum_t lenum;
    int font_index = (pcmap->num_fonts <= 1 ? 0 : -1);
    int code;

    for (gs_cmap_lookups_enum_init(pcmap, which, &lenum);
	 (code = gs_cmap_enum_next_lookup(&lenum)) == 0; ) {
	gs_cmap_lookups_enum_t counter;
	int num_entries = 0;
	int gi;

	if (font_index_only >= 0 && lenum.entry.font_index != font_index_only)
	    continue;
	if (font_index_only < 0 && lenum.entry.font_index != font_index) {
	    pprintd1(s, "%d usefont\n", lenum.entry.font_index);
	    font_index = lenum.entry.font_index;
	}
	/* Count the number of entries in this lookup range. */
	counter = lenum;
	while (gs_cmap_enum_next_entry(&counter) == 0)
	    ++num_entries;
	for (gi = 0; gi < num_entries; gi += 100) {
	    int i = gi, ni = min(i + 100, num_entries);
	    const char *end;

	    pprintd1(s, "%d ", ni - i);
	    if (lenum.entry.key_is_range) {
		if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) {
		    stream_puts(s, pcmo->beginrange);
		    end = pcmo->endrange;
		} else {	/* must be def, not notdef */
		    stream_puts(s, "beginbfrange\n");
		    end = "endbfrange\n";
		}
	    } else {
		if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) {
		    stream_puts(s, pcmo->beginchar);
		    end = pcmo->endchar;
		} else {	/* must be def, not notdef */
		    stream_puts(s, "beginbfchar\n");
		    end = "endbfchar\n";
		}
	    }
	    for (; i < ni; ++i) {
		int j;
		long value;
		int value_size;

		DISCARD(gs_cmap_enum_next_entry(&lenum)); /* can't fail */
		value_size = lenum.entry.value.size;
		for (j = 0; j <= lenum.entry.key_is_range; ++j) {
		    stream_putc(s, '<');
		    pput_hex(s, lenum.entry.key[j], lenum.entry.key_size);
		    stream_putc(s, '>');
		}
		for (j = 0, value = 0; j < value_size; ++j)
		    value = (value << 8) + lenum.entry.value.data[j];
		switch (lenum.entry.value_type) {
		case CODE_VALUE_CID:
		case CODE_VALUE_NOTDEF:
		    pprintld1(s, "%ld", value);
		    break;
		case CODE_VALUE_CHARS:
		    stream_putc(s, '<');
		    pput_hex(s, lenum.entry.value.data, value_size);
		    stream_putc(s, '>');
		    break;
		case CODE_VALUE_GLYPH: {
		    gs_const_string str;
		    int code = pcmap->glyph_name(mem, (gs_glyph)value, &str,
						 pcmap->glyph_name_data);

		    if (code < 0)
			return code;
		    stream_putc(s, '/');
		    code = put_name_chars(s, str.data, str.size);
		    if (code < 0)
			return code;
		}
		    break;
		default:	/* not possible */
		    return_error(gs_error_unregistered);
		}
		stream_putc(s, '\n');
	    }
	    stream_puts(s, end);
	}
    }
    return code;
}
Exemplo n.º 9
0
void
gp_set_file_binary(int prnfno, int binary)
{
    DISCARD(setmode_binary(prnfno, binary != 0));
}
Exemplo n.º 10
0
/*
 * Combine a file name with a prefix.
 * Concatenates two paths and reduce parent references and current 
 * directory references from the concatenation when possible.
 * The trailing zero byte is being added.
 *
 * Returns "gp_combine_success" if OK and sets '*blen' to the length of
 * the combined string. If the combined string is too small for the buffer
 * length passed in (as defined by the initial value of *blen), then the
 * "gp_combine_small_buffer" code is returned.
 *
 * Also tolerates/skips leading IODevice specifiers such as %os% or %rom%
 * When there is a leading '%' in the 'fname' no other processing is done.
 *
 * Examples : 
 *	"/gs/lib" + "../Resource/CMap/H" --> "/gs/Resource/CMap/H"
 *	"C:/gs/lib" + "../Resource/CMap/H" --> "C:/gs/Resource/CMap/H"
 *	"hard disk:gs:lib" + "::Resource:CMap:H" --> 
 *		"hard disk:gs:Resource:CMap:H"
 *	"DUA1:[GHOSTSCRIPT.LIB" + "-.RESOURCE.CMAP]H" --> 
 *		"DUA1:[GHOSTSCRIPT.RESOURCE.CMAP]H"
 *      "\\server\share/a/b///c/../d.e/./" + "../x.e/././/../../y.z/v.v" --> 
 *		"\\server\share/a/y.z/v.v"
 *	"%rom%lib/" + "gs_init.ps" --> "%rom%lib/gs_init.ps
 *	"" + "%rom%lib/gs_init.ps" --> "%rom%lib/gs_init.ps"
 */
gp_file_name_combine_result
gp_file_name_combine_generic(const char *prefix, uint plen, const char *fname, uint flen, 
		    bool no_sibling, char *buffer, uint *blen)
{
    /*
     * THIS CODE IS SHARED FOR MULTIPLE PLATFORMS.
     * PLEASE DON'T CHANGE IT FOR A SPECIFIC PLATFORM.
     * Change gp_file_name_combine instead.
     */
    char *bp = buffer, *bpe = buffer + *blen;
    const char *ip, *ipe;
    uint slen;
    uint infix_type = 0; /* 0=none, 1=current, 2=parent. */
    uint infix_len = 0;
    uint rlen = gp_file_name_root(fname, flen);
    /* We need a special handling of infixes only immediately after a drive. */

    if ( flen > 0 && fname[0] == '%') {
    	/* IoDevice -- just return the fname as-is since this */
	/* function only handles the default file system */
	/* NOTE: %os% will subvert the normal processing of prefix and fname */
	ip = fname;
	*blen = flen;
	if (!append(&bp, bpe, &ip, flen))
	    return gp_combine_small_buffer;
	return gp_combine_success;
    }
    if (rlen != 0) {
        /* 'fname' is absolute, ignore the prefix. */
	ip = fname;
	ipe = fname + flen;
    } else {
        /* Concatenate with prefix. */
	ip = prefix;
	ipe = prefix + plen;
	rlen = gp_file_name_root(prefix, plen);
    }
    if (!append(&bp, bpe, &ip, rlen))
	return gp_combine_small_buffer;
    slen = gs_file_name_check_separator(bp, buffer - bp, bp); /* Backward search. */
    if (rlen != 0 && slen == 0) {
	/* Patch it against names like "c:dir" on Windows. */
	const char *sep = gp_file_name_directory_separator();

	slen = strlen(sep);
	if (!append(&bp, bpe, &sep, slen))
	    return gp_combine_small_buffer;
	rlen += slen;
    }
    for (;;) {
	const char *item = ip;
	uint ilen;

	slen = search_separator(&ip, ipe, item, 1);
	ilen = ip - item;
	if (ilen == 0 && !gp_file_name_is_empty_item_meanful()) {
	    ip += slen;
	    slen = 0;
	} else if (gp_file_name_is_current(item, ilen)) {
	    /* Skip the reference to 'current', except the starting one.
	     * We keep the starting 'current' for platforms, which
	     * require relative paths to start with it.
	     */
	    if (bp == buffer) {
		if (!append(&bp, bpe, &item, ilen))
		    return gp_combine_small_buffer;
		infix_type = 1;
		infix_len = ilen;
	    } else {
		ip += slen;
		slen = 0;
	    }
	} else if (!gp_file_name_is_parent(item, ilen)) {
	    if (!append(&bp, bpe, &item, ilen))
		return gp_combine_small_buffer;
	    /* The 'item' pointer is now broken; it may be restored using 'ilen'. */
	} else if (bp == buffer + rlen + infix_len) {
	    /* Input is a parent and the output only contains a root and an infix. */
	    if (rlen != 0)
		return gp_combine_cant_handle;
	    switch (infix_type) {
		case 1:
		    /* Replace the infix with parent. */
		    bp = buffer + rlen; /* Drop the old infix, if any. */
		    infix_len = 0;
		    /* Falls through. */
		case 0:
		    /* We have no infix, start with parent. */
		    if ((no_sibling && ipe == fname + flen && flen != 0) || 
			    !gp_file_name_is_partent_allowed())
			return gp_combine_cant_handle;
		    /* Falls through. */
		case 2:
		    /* Append one more parent - falls through. */
		    DO_NOTHING;
	    }
	    if (!append(&bp, bpe, &item, ilen))
		return gp_combine_small_buffer;
	    infix_type = 2;
	    infix_len += ilen;
	    /* Recompute the separator length. We cannot use the old slen on Mac OS. */
	    slen = gs_file_name_check_separator(ip, ipe - ip, ip);
	} else {
	    /* Input is a parent and the output continues after infix. */
	    /* Unappend the last separator and the last item. */
	    uint slen1 = gs_file_name_check_separator(bp, buffer + rlen - bp, bp); /* Backward search. */
	    char *bie = bp - slen1;

	    bp = bie;
	    DISCARD(search_separator((const char **)&bp, buffer + rlen, bp, -1));
	    /* The cast above quiets a gcc warning. We believe it's a bug in the compiler. */
	    /* Skip the input with separator. We cannot use slen on Mac OS. */
	    ip += gs_file_name_check_separator(ip, ipe - ip, ip);
	    if (no_sibling) {
		const char *p = ip;

		DISCARD(search_separator(&p, ipe, ip, 1));
		if (p - ip != bie - bp || memcmp(ip, bp, p - ip))    
		    return gp_combine_cant_handle;
	    }
	    slen = 0;
	}
	if (slen) {
	    if (bp == buffer + rlen + infix_len)
		infix_len += slen;
	    if (!append(&bp, bpe, &ip, slen))
		return gp_combine_small_buffer;
	}
	if (ip == ipe) {
	    if (ipe == fname + flen) {
		/* All done.
		 * Note that the case (prefix + plen == fname && flen == 0)
		 * falls here without appending a separator.
		 */
		const char *zero="";

		if (bp == buffer) {
		    /* Must not return empty path. */
		    const char *current = gp_file_name_current();
		    int clen = strlen(current);

		    if (!append(&bp, bpe, &current, clen))
			return gp_combine_small_buffer;
		}
		*blen = bp - buffer;
		if (!append(&bp, bpe, &zero, 1))
		    return gp_combine_small_buffer;
		return gp_combine_success;
	    } else {
	        /* ipe == prefix + plen */
		/* Switch to fname. */
		ip = fname;
		ipe = fname + flen;
		if (slen == 0) {
		    /* Insert a separator. */
		    const char *sep;
    
		    slen = search_separator(&ip, ipe, fname, 1);
		    sep = (slen != 0 ? gp_file_name_directory_separator() 
		                    : gp_file_name_separator());
		    slen = strlen(sep);
		    if (bp == buffer + rlen + infix_len)
			infix_len += slen;
		    if (!append(&bp, bpe, &sep, slen))
			return gp_combine_small_buffer;
		    ip = fname; /* Switch to fname. */
		}
	    }
	}
    }
}
Exemplo n.º 11
0
bp_Table * bp_parseTable(bp_Context * context, xmlNodePtr node) {
	bp_Table * result = malloc(sizeof(bp_Table));
	bp_Node * const parent = &result->node;
	xmlAttrPtr attr;
	xmlNodePtr child, grand;

	bp_pushBlockBorder(context);
	bp_pushBlockInside(context);
	bp_pushInline(context);

	bp_initNode(&result->node, BPE_TABLE);
	result->_float = bp_defaultFloatAttributes;
	result->blockOutside = *(context->blockOutside);
	result->caption = NULL;
	result->nCols = 0;
	result->nRows = 0;
	
	for (attr = node->properties; attr; attr = attr->next) {
		bp_parseFloatAttribute(context, &result->_float, attr);
		bp_parseBlockOutsideAttribute(context, &result->blockOutside, attr);
		bp_parseBlockBorderAttribute(context, context->blockBorder, attr);
		bp_parseBlockInsideAttribute(context, context->blockInside, attr);
		bp_parseInlineAttribute(context, context->inlineAttr, attr);
	}

	result->blockBorder = *(context->blockBorder); // shared with children

	for (child = node->children; child; child = child->next) {
		switch(ELEM(child)) {
			case BPE_TR: result->nRows++; break;
			case BPE_TC: result->nCols++; break;
			case BPE_CAPTION:
				result->caption = bp_parseCaption(context, child);
			default: DISCARD(child);
		}
	}

	if (result->nRows) {
		int * colHeights = NULL; 
		int col, row = 0;
		result->nCols = 0;

		for (child = node->children; child; child = child->next) {
			if(ELEM(child) == BPE_TR) {
				bp_pushBlockBorder(context);
				bp_pushBlockInside(context);
				bp_pushInline(context);

				for (attr = child->properties; attr; attr = attr->next) {
					bp_parseBlockBorderAttribute(context, context->blockBorder, attr);
					bp_parseBlockInsideAttribute(context, context->blockInside, attr);
					bp_parseInlineAttribute(context, context->inlineAttr, attr);
				}
				
				col = 0;
				for (grand = child->children; grand; grand = grand->next) {
					while ((col < result->nCols) && (colHeights[col] >= row)) col++;
							
					if(ELEM(grand) == BPE_TD) {
						bp_Cell * cell = bp_parseCell(context, grand, row, col);

						ADD(cell);
						
						if (cell->endCol >= result->nCols) {
							result->nCols = cell->endCol + 1;
							colHeights = realloc(colHeights, result->nCols * sizeof(int));
						}
						
						for (col=cell->startCol; col <= cell->endCol; col++) {
							colHeights[col] = cell->endRow;
						}
					} else {
						DISCARD(grand);
					}
				}

				bp_popBlockBorder(context);
				bp_popBlockInside(context);
				bp_popInline(context);
				row++;
			}
		}

		if(colHeights) free(colHeights);
	} else if (result->nCols) {
		int * rowWidths = NULL; 
		int col = 0, row;
		result->nRows = 0;

		for (child = node->children; child; child = child->next) {
			if(ELEM(child) == BPE_TC) {
				bp_pushBlockBorder(context);
				bp_pushBlockInside(context);
				bp_pushInline(context);

				for (attr = child->properties; attr; attr = attr->next) {
					bp_parseBlockBorderAttribute(context, context->blockBorder, attr);
					bp_parseBlockInsideAttribute(context, context->blockInside, attr);
					bp_parseInlineAttribute(context, context->inlineAttr, attr);
				}
				
				row = 0;
				for (grand = child->children; grand; grand = grand->next) {
					while ((row < result->nRows) && (rowWidths[row] >= col)) row++;
							
					if(ELEM(grand) == BPE_TD) {
						bp_Cell * cell = bp_parseCell(context, grand, row, col);

						ADD(cell);
						
						if (cell->endRow >= result->nRows) {
							result->nRows = cell->endRow + 1;
							rowWidths = realloc(rowWidths, result->nRows * sizeof(int));
						}
						
						for (row=cell->startRow; row <= cell->endRow; row++) {
							rowWidths[row] = cell->endCol;
						}
					} else {
						DISCARD(grand);
					}
				}

				bp_popBlockBorder(context);
				bp_popBlockInside(context);
				bp_popInline(context);
				col++;
			}
		}

		if(rowWidths) free(rowWidths);
	}

	bp_popBlockBorder(context);
	bp_popBlockInside(context);
	bp_popInline(context);

	return result;
}
Exemplo n.º 12
0
bp_Page * bp_parsePage(bp_Context * context, xmlNodePtr node) {
	bp_Page * result = malloc(sizeof(bp_Page));
	bp_Node * const parent = &result->node;
	xmlAttrPtr attr;
	xmlNodePtr child;

	bp_pushBlockOutside(context);
	bp_pushBlockBorder(context);
	bp_pushBlockInside(context);
	bp_pushInline(context);

	bp_initNode(&result->node, BPE_PAGE);
	result->title = NULL;

	for (attr = node->properties; attr; attr = attr->next) {
		bp_parseBlockOutsideAttribute(context, context->blockOutside, attr);
		bp_parseBlockBorderAttribute(context, context->blockBorder, attr);
		bp_parseBlockInsideAttribute(context, context->blockInside, attr);
		bp_parseInlineAttribute(context, context->inlineAttr, attr);
	}

	for (child = node->children; child; child = child->next) {
		switch(ELEM(child)) {
			case BPE_TITLE:
				if (!result->title) {
					xmlNodePtr grandchild = child->children;
					if (ELEM(grandchild) == BPE_TEXT) {
						int len = strlen(grandchild->content);
						char * title_string = malloc(++len);
						memcpy(title_string, grandchild->content, len);
						result->title = title_string;
					} else {
						DISCARD(grandchild);
					}
				} else {
					DISCARD(child);
				}
				break;
			case BPE_REF:
				bp_parseNavRef(context, child, result);
				break;
			case BPE_BLOCK:
				ADD(bp_parseBlock(context, child));
				break;
			case BPE_IMAGE:
				ADD(bp_parseImage(context, child));
				break;
			case BPE_TABLE:
				ADD(bp_parseTable(context, child));
				break;
			case BPE_LABEL:
				ADD(bp_parseLabel(context, child));
				break;
			default:
				DISCARD(child);
		}
	}

	bp_popBlockOutside(context);
	bp_popBlockBorder(context);
	bp_popBlockInside(context);
	bp_popInline(context);

	return result;
}
Exemplo n.º 13
0
bp_Book * bp_parseBook(bp_Context * context, xmlNodePtr node) {
	bp_Book * result = malloc(sizeof(bp_Book));
	bp_Node * const parent = &result->node;
	bp_Node * page;
	xmlAttrPtr attr;
	xmlNodePtr child;
	bp_Page ** pages;
	st_data * fontSym;

	context->blockOutside = (void *) &bp_defaultBlockOutsideAttributes;
	context->blockBorder  = (void *) &bp_defaultBlockBorderAttributes;
	context->blockInside  = (void *) &bp_defaultBlockInsideAttributes;
	context->inlineAttr      = (void *) &bp_defaultInlineAttributes;

	bp_pushBlockOutside(context);
	bp_pushBlockBorder(context);
	bp_pushBlockInside(context);
	bp_pushInline(context);

	bp_initNode(&result->node, BPE_BOOK);
	result->width = 528;
	result->height = 320;
	result->background = load_texture_cache_deferred("textures/book1.bmp",0);
	fontSym = st_lookup (bp_fonts, "default");
	if (fontSym != NULL) {
		result->fontFace = fontSym->num;
	} else {
		LOG_ERROR("FATAL: default font missing in font symbol table\n");
		exit(1);
	}
	result->layout = BPL_BOOK;
	result->blockProgression = BPD_DOWN;
	result->inlineProgression = BPD_RIGHT;
	result->pages = NULL;
	result->nPages = 0;

	for (attr = node->properties; attr; attr = attr->next) {
		bp_parseBlockOutsideAttribute(context, context->blockOutside, attr);
		bp_parseBlockBorderAttribute(context, context->blockBorder, attr);
		bp_parseBlockInsideAttribute(context, context->blockInside, attr);
		bp_parseInlineAttribute(context, context->inlineAttr, attr);
	}

	for (child = node->children; child; child = child->next) {
		switch(ELEM(child)) {
			case BPE_PAGE:
				result->nPages++;
				ADD(bp_parsePage(context, child));
				break;
			default:
				DISCARD(child);
		}
	}

	bp_popBlockOutside(context);
	bp_popBlockBorder(context);
	bp_popBlockInside(context);
	bp_popInline(context);

	/* create page index */
	pages = calloc(result->nPages, sizeof(bp_Page *));
	result->pages = pages;
	for (page = parent->children; page; page = page->next) {
		*pages++ = (bp_Page *) page;
	}
	
	return result;
}
Exemplo n.º 14
0
void mbadblocks(int argc, char **argv, int type)
{
	unsigned int i;
	unsigned int startSector=2;
	unsigned int endSector=0;
	struct MainParam_t mp;
	Fs_t *Fs;
	Stream_t *Dir;
	int ret;
	char *filename = NULL;
	char c;
	unsigned int badClus;
	int sectorMode=0;
	int writeMode=0;

	while ((c = getopt(argc, argv, "i:s:cwS:E:")) != EOF) {
		switch(c) {
		case 'i':
			set_cmd_line_image(optarg, 0);
			break;
		case 'c':
			checkListTwice(filename);
			filename = strdup(optarg);
			break;
		case 's':
			checkListTwice(filename);
			filename = strdup(optarg);
			sectorMode = 1;
			break;
		case 'S':
			startSector = atol(optarg); 
			break;
		case 'E':
			endSector = atol(optarg); 
			break;
		case 'w':
			writeMode = 1;
			break;
		case 'h':
			usage(0);
		default:
			usage(1);
		}
	}

	if (argc != optind+1 ||
	    !argv[optind][0] || argv[optind][1] != ':' || argv[optind][2]) {
		usage(1);
	}

	init_mp(&mp);

	Dir = open_root_dir(argv[optind][0], O_RDWR, NULL);
	if (!Dir) {
		fprintf(stderr,"%s: Cannot initialize drive\n", argv[0]);
		exit(1);
	}

	Fs = (Fs_t *)GetFs(Dir);
	in_len = Fs->cluster_size * Fs->sector_size;
	in_buf = malloc(in_len);
	if(!in_buf) {
		printOom();
		ret = 1;
		goto exit_0;
	}
	if(writeMode) {
		int i;
		pat_buf=malloc(in_len * N_PATTERN);
		if(!pat_buf) {
			printOom();
			ret = 1;
			goto exit_0;
		}
		srandom(time(NULL));
		for(i=0; i < in_len * N_PATTERN; i++) {
			pat_buf[i] = random();
		}
	}
	for(i=0; i < Fs->clus_start; i++ ){
		ret = READS(Fs->Next, in_buf, 
			    sectorsToBytes((Stream_t*)Fs, i), Fs->sector_size);
		if( ret < 0 ){
			perror("early error");
			goto exit_0;
		}
		if(ret < (signed int) Fs->sector_size){
			fprintf(stderr,"end of file in file_read\n");
			ret = 1;
			goto exit_0;
		}
	}
	ret = 0;

	badClus = Fs->last_fat + 1;

	if(startSector < 2)
		startSector = 2;
	if(endSector > Fs->num_clus + 2 || endSector <= 0) 
		endSector = Fs->num_clus + 2;

	if(filename) {
		char line[80];

		FILE *f = fopen(filename, "r");
		if(f == NULL) {
			fprintf(stderr, "Could not open %s (%s)\n",
				filename, strerror(errno));
			ret = 1;
			goto exit_0;
		}
		while(fgets(line, sizeof(line), f)) {
			char *ptr = line + strspn(line, " \t");
			long offset = strtoul(ptr, 0, 0);
			if(sectorMode)
				offset = (offset-Fs->clus_start)/Fs->cluster_size + 2;
			if(offset < 2) {
				fprintf(stderr, "Sector before start\n");
			} else if(offset >= Fs->num_clus) {
				fprintf(stderr, "Sector beyond end\n");
			} else {
				mark(Fs, offset, badClus);
				ret = 1;
			}
		}
	} else {
		Stream_t *dev;
		dev = Fs->Next;
		if(dev->Next)
			dev = dev->Next;

		in_len = Fs->cluster_size * Fs->sector_size;
		if(writeMode) {
			/* Write pattern */
			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, 
					    pat_buf + in_len * (i % N_PATTERN),
					    1);
			}

			/* Flush cache, so that we are sure we read the data
			   back from disk, rather than from the cache */
			if(!got_signal)
				DISCARD(dev);

			/* Read data back, and compare to pattern */
			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, 
					    pat_buf + in_len * (i % N_PATTERN),
					    0);
			}

		} else {

			for(i=startSector; i< endSector; i++){
				if(got_signal)
					break;
				progress(i, Fs->num_clus);
				ret |= scan(Fs, dev, i, badClus, NULL, 0);
			}
		}
	}
 exit_0:
	FREE(&Dir);
	exit(ret);
}