static int prepare_data(PyObject *obj, xorn_obtype_t *type_return, const void **data_return) { if (PyObject_TypeCheck(obj, &ArcType)) prepare_arc((Arc *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &BoxType)) prepare_box((Box *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &CircleType)) prepare_circle((Circle *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &ComponentType)) prepare_component((Component *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &LineType)) prepare_line((Line *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &NetType)) prepare_net((Net *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &PathType)) prepare_path((Path *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &PictureType)) prepare_picture((Picture *)obj, type_return, data_return); else if (PyObject_TypeCheck(obj, &TextType)) prepare_text((Text *)obj, type_return, data_return); else return -1; return 0; }
static void normal_draw(struct lstopo_output *loutput, hwloc_obj_t level, unsigned depth, unsigned x, unsigned y) { struct lstopo_obj_userdata *lud = level->userdata; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; if (loutput->drawing == LSTOPO_DRAWING_PREPARE) { /* compute children size and position, our size, and save it */ prepare_text(loutput, level); lud->width = lud->textwidth + gridsize + FONTGRIDSIZE; lud->height = gridsize + (fontsize + FONTGRIDSIZE) * lud->ntext; place_children(loutput, level, gridsize, gridsize + (fontsize + FONTGRIDSIZE) * lud->ntext); } else { /* LSTOPO_DRAWING_DRAW */ struct draw_methods *methods = loutput->methods; struct lstopo_style style; unsigned totwidth, totheight; /* restore our size that was computed during prepare */ totwidth = lud->width; totheight = lud->height; lstopo_set_object_color(loutput, level, &style); methods->box(loutput, &style.bg, depth, x, totwidth, y, totheight); draw_text(loutput, level, &style.t, depth-1, x + gridsize, y + gridsize); /* Draw sublevels for real */ draw_children(loutput, level, depth-1, x, y); } }
static void pci_device_draw(struct lstopo_output *loutput, hwloc_obj_t level, unsigned depth, unsigned x, unsigned y) { struct lstopo_obj_userdata *lud = level->userdata; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned overlaidoffset = 0; if (lud->pci_collapsed > 1) { /* additional depths and height for overlaid boxes */ depth -= 2; if (lud->pci_collapsed > 2) { overlaidoffset = gridsize; } else { overlaidoffset = gridsize/2; } } if (loutput->drawing == LSTOPO_DRAWING_PREPARE) { /* compute children size and position, our size, and save it */ prepare_text(loutput, level); lud->width = lud->textwidth + gridsize + overlaidoffset + FONTGRIDSIZE; lud->height = fontsize + gridsize + overlaidoffset + FONTGRIDSIZE; place_children(loutput, level, gridsize, fontsize + gridsize + FONTGRIDSIZE); } else { /* LSTOPO_DRAWING_DRAW */ struct draw_methods *methods = loutput->methods; struct lstopo_style style; unsigned totwidth, totheight; /* restore our size that was computed during prepare */ totwidth = lud->width; totheight = lud->height; lstopo_set_object_color(loutput, level, &style); if (lud->pci_collapsed > 1) { methods->box(loutput, &style.bg, depth+2, x + overlaidoffset, totwidth - overlaidoffset, y + overlaidoffset, totheight - overlaidoffset); if (lud->pci_collapsed > 2) methods->box(loutput, &style.bg, depth+1, x + overlaidoffset/2, totwidth - overlaidoffset, y + overlaidoffset/2, totheight - overlaidoffset); methods->box(loutput, &style.bg, depth, x, totwidth - overlaidoffset, y, totheight - overlaidoffset); } else { methods->box(loutput, &style.bg, depth, x, totwidth, y, totheight); } draw_text(loutput, level, &style.t, depth-1, x + gridsize, y + gridsize); /* Draw sublevels for real */ draw_children(loutput, level, depth-1, x, y); } }
static void cache_draw(struct lstopo_output *loutput, hwloc_obj_t level, unsigned depth, unsigned x, unsigned y) { struct lstopo_obj_userdata *lud = level->userdata; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned myheight = fontsize + gridsize + FONTGRIDSIZE; /* totheight also contains children outside of this actual cache box */ if (loutput->drawing == LSTOPO_DRAWING_PREPARE) { /* compute children size and position, our size, and save it */ prepare_text(loutput, level); lud->width = lud->textwidth + gridsize + FONTGRIDSIZE; lud->height = myheight; place_children(loutput, level, 0, myheight + gridsize); } else { /* LSTOPO_DRAWING_DRAW */ struct draw_methods *methods = loutput->methods; struct lstopo_style style; unsigned totwidth; unsigned myoff = 0; /* restore our size that was computed during prepare */ totwidth = lud->width; if (lud->above_children.kinds) { /* display above_children even above the cache itself */ myoff = lud->above_children.height + gridsize; lud->above_children.yrel = 0; } lstopo_set_object_color(loutput, level, &style); methods->box(loutput, &style.bg, depth, x, totwidth, y + myoff, myheight); draw_text(loutput, level, &style.t, depth-1, x + gridsize, y + gridsize + myoff); /* Draw sublevels for real */ draw_children(loutput, level, depth-1, x, y); } }
static void find_identical_ends (struct file_data filevec[]) { word *w0, *w1; char *p0, *p1, *buffer0, *buffer1; char const *end0, *beg0; char const **linbuf0, **linbuf1; lin i, lines; size_t n0, n1; lin alloc_lines0, alloc_lines1; lin buffered_prefix, prefix_count, prefix_mask; lin middle_guess, suffix_guess; slurp (&filevec[0]); prepare_text (&filevec[0]); if (filevec[0].desc != filevec[1].desc) { slurp (&filevec[1]); prepare_text (&filevec[1]); } else { filevec[1].buffer = filevec[0].buffer; filevec[1].bufsize = filevec[0].bufsize; filevec[1].buffered = filevec[0].buffered; filevec[1].missing_newline = filevec[0].missing_newline; } /* Find identical prefix. */ w0 = filevec[0].buffer; w1 = filevec[1].buffer; p0 = buffer0 = (char *) w0; p1 = buffer1 = (char *) w1; n0 = filevec[0].buffered; n1 = filevec[1].buffered; if (p0 == p1) /* The buffers are the same; sentinels won't work. */ p0 = p1 += n1; else { /* Insert end sentinels, in this case characters that are guaranteed to make the equality test false, and thus terminate the loop. */ if (n0 < n1) p0[n0] = ~p1[n0]; else p1[n1] = ~p0[n1]; /* Loop until first mismatch, or to the sentinel characters. */ /* Compare a word at a time for speed. */ while (*w0 == *w1) w0++, w1++; /* Do the last few bytes of comparison a byte at a time. */ p0 = (char *) w0; p1 = (char *) w1; while (*p0 == *p1) p0++, p1++; /* Don't mistakenly count missing newline as part of prefix. */ if (ROBUST_OUTPUT_STYLE (output_style) && ((buffer0 + n0 - filevec[0].missing_newline < p0) != (buffer1 + n1 - filevec[1].missing_newline < p1))) p0--, p1--; } /* Now P0 and P1 point at the first nonmatching characters. */ /* Skip back to last line-beginning in the prefix, and then discard up to HORIZON_LINES lines from the prefix. */ i = horizon_lines; while (p0 != buffer0 && (p0[-1] != '\n' || i--)) p0--, p1--; /* Record the prefix. */ filevec[0].prefix_end = p0; filevec[1].prefix_end = p1; /* Find identical suffix. */ /* P0 and P1 point beyond the last chars not yet compared. */ p0 = buffer0 + n0; p1 = buffer1 + n1; if (! ROBUST_OUTPUT_STYLE (output_style) || filevec[0].missing_newline == filevec[1].missing_newline) { end0 = p0; /* Addr of last char in file 0. */ /* Get value of P0 at which we should stop scanning backward: this is when either P0 or P1 points just past the last char of the identical prefix. */ beg0 = filevec[0].prefix_end + (n0 < n1 ? 0 : n0 - n1); /* Scan back until chars don't match or we reach that point. */ for (; p0 != beg0; p0--, p1--) if (*p0 != *p1) { /* Point at the first char of the matching suffix. */ beg0 = p0; break; } /* Are we at a line-beginning in both files? If not, add the rest of this line to the main body. Discard up to HORIZON_LINES lines from the identical suffix. Also, discard one extra line, because shift_boundaries may need it. */ i = horizon_lines + !((buffer0 == p0 || p0[-1] == '\n') && (buffer1 == p1 || p1[-1] == '\n')); while (i-- && p0 != end0) while (*p0++ != '\n') continue; p1 += p0 - beg0; } /* Record the suffix. */ filevec[0].suffix_begin = p0; filevec[1].suffix_begin = p1; /* Calculate number of lines of prefix to save. prefix_count == 0 means save the whole prefix; we need this for options like -D that output the whole file, or for enormous contexts (to avoid worrying about arithmetic overflow). We also need it for options like -F that output some preceding line; at least we will need to find the last few lines, but since we don't know how many, it's easiest to find them all. Otherwise, prefix_count != 0. Save just prefix_count lines at start of the line buffer; they'll be moved to the proper location later. Handle 1 more line than the context says (because we count 1 too many), rounded up to the next power of 2 to speed index computation. */ if (no_diff_means_no_output && ! function_regexp.fastmap && context < LIN_MAX / 4 && context < n0) { middle_guess = guess_lines (0, 0, p0 - filevec[0].prefix_end); suffix_guess = guess_lines (0, 0, buffer0 + n0 - p0); for (prefix_count = 1; prefix_count <= context; prefix_count *= 2) continue; alloc_lines0 = (prefix_count + middle_guess + MIN (context, suffix_guess)); } else { prefix_count = 0; alloc_lines0 = guess_lines (0, 0, n0); } prefix_mask = prefix_count - 1; lines = 0; linbuf0 = xmalloc (alloc_lines0 * sizeof *linbuf0); p0 = buffer0; /* If the prefix is needed, find the prefix lines. */ if (! (no_diff_means_no_output && filevec[0].prefix_end == p0 && filevec[1].prefix_end == p1)) { end0 = filevec[0].prefix_end; while (p0 != end0) { lin l = lines++ & prefix_mask; if (l == alloc_lines0) { if (PTRDIFF_MAX / (2 * sizeof *linbuf0) <= alloc_lines0) xalloc_die (); alloc_lines0 *= 2; linbuf0 = xrealloc (linbuf0, alloc_lines0 * sizeof *linbuf0); } linbuf0[l] = p0; while (*p0++ != '\n') continue; } } buffered_prefix = prefix_count && context < lines ? context : lines; /* Allocate line buffer 1. */ middle_guess = guess_lines (lines, p0 - buffer0, p1 - filevec[1].prefix_end); suffix_guess = guess_lines (lines, p0 - buffer0, buffer1 + n1 - p1); alloc_lines1 = buffered_prefix + middle_guess + MIN (context, suffix_guess); if (alloc_lines1 < buffered_prefix || PTRDIFF_MAX / sizeof *linbuf1 <= alloc_lines1) xalloc_die (); linbuf1 = xmalloc (alloc_lines1 * sizeof *linbuf1); if (buffered_prefix != lines) { /* Rotate prefix lines to proper location. */ for (i = 0; i < buffered_prefix; i++) linbuf1[i] = linbuf0[(lines - context + i) & prefix_mask]; for (i = 0; i < buffered_prefix; i++) linbuf0[i] = linbuf1[i]; } /* Initialize line buffer 1 from line buffer 0. */ for (i = 0; i < buffered_prefix; i++) linbuf1[i] = linbuf0[i] - buffer0 + buffer1; /* Record the line buffer, adjusted so that linbuf[0] points at the first differing line. */ filevec[0].linbuf = linbuf0 + buffered_prefix; filevec[1].linbuf = linbuf1 + buffered_prefix; filevec[0].linbuf_base = filevec[1].linbuf_base = - buffered_prefix; filevec[0].alloc_lines = alloc_lines0 - buffered_prefix; filevec[1].alloc_lines = alloc_lines1 - buffered_prefix; filevec[0].prefix_lines = filevec[1].prefix_lines = lines; }