📄 datadpy.c
字号:
}/* * Removes a dataDpy from its parent's list of children. */static void DeleteList(head, dataDpy)DataDpyList **head;DataDpyRec *dataDpy;{ DataDpyList *p, *q; if ((p = *head)) { if (p->dataDpy == dataDpy) *head = p->next; else { for (q = p->next; q && q->dataDpy != dataDpy;) { p = q; q = p->next; } if (q) p->next = q->next; } }} /* * Pop down a dataDpy and all its descendants, freeing storage and * reinitializing fields. */static void pop_down(dataDpy)DataDpyRec *dataDpy;{ DataDpyList *p, *q; XtPopdown(dataDpy->popupshell); XtFree((void*)dataDpy->linepos); XtFree(dataDpy->buf); dataDpy->buf = NULL; dataDpy->buflen = 0; dataDpy->linepos = NULL; dataDpy->state = UNUSED; dataDpy->parent = NULL; for (p = dataDpy->childlist; p;) { pop_down(p->dataDpy); q = p; p = p->next; XtFree((void*)q); } dataDpy->childlist = NULL;}/* * Invoked by a ButtonPress event on the label of a data display to * pop down itself and its descendants. *//* ARGSUSED */#ifdef OBSOLETEstatic void DestroyDataPopup(w, dataDpy, event) Widget w; DataDpyRec *dataDpy; XEvent *event;#else/* CRL mod 25 4/12/91 GWC - changed label widget to command widget */static void DestroyDataCallback(w, dataDpy, call_data) Widget w; DataDpyRec *dataDpy; caddr_t call_data;#endif{ if (!dataDpy->parent) DeleteList(&TopParentList, dataDpy); else DeleteList(&dataDpy->parent->childlist, dataDpy); pop_down(dataDpy);}/* * Position the data display on the screen to reflect the parent-child * relationship. */static void MovePopup(dataDpy)DataDpyRec *dataDpy;{ Arg args[MAXARGS]; Cardinal n; Screen *screen; int popupHeight, popupWidth, screenHeight, screenWidth; Position x, y; Dimension dataDpyWidth, dataDpyHeight, dataDpyBorderWidth, labelHeight, labelBorderWidth, width, height, borderWidth; DataDpyList *p, *q; Parent = NULL; if (!dataDpy->parent) p = TopParentList; else p = dataDpy->parent->childlist; /* Look for its previous sibling */ for (q = p->next; q && q->dataDpy != dataDpy;) { p = q; q = q->next; } /* If a sibling exists, place the new popup right next to it */ if (q) { n = 0; XtSetArg(args[n], XtNwidth, (XtArgVal) &width); n++; XtSetArg(args[n], XtNborderWidth, (XtArgVal) &borderWidth); n++; XtGetValues(p->dataDpy->popupshell, args, n); XtTranslateCoords(p->dataDpy->popupshell, 0, 0, &x, &y); x += width; y -= borderWidth; } else { /* no siblings */ /* this is the very first popup */ if (!dataDpy->parent) { x = 0; y = 0; } /* place it under its parent */ else { n = 0; XtSetArg(args[n], XtNheight, (XtArgVal) &height); n++; XtGetValues(dataDpy->parent->popupshell, args, n); XtTranslateCoords(dataDpy->parent->popupshell, 30, (Position)height, &x, &y); } } /* Make sure the popup does not go outside of the screen */ n = 0; XtSetArg(args[n], XtNwidth, (XtArgVal) &dataDpyWidth); n++; XtSetArg(args[n], XtNheight, (XtArgVal) &dataDpyHeight); n++; XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++; XtGetValues(dataDpy->dataDpyWindow, args, n); n = 0; XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++; XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++; XtGetValues(dataDpy->label, args, n); popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth + 2*dataDpyBorderWidth; popupWidth = dataDpyWidth; screen = XtScreen(toplevel); screenHeight = XHeightOfScreen(screen); screenWidth = XWidthOfScreen(screen); if (x + popupWidth > screenWidth && y + popupHeight > screenHeight) { x = screenWidth - popupWidth; y = screenHeight - popupHeight; } else if (x + popupWidth > screenWidth) x = screenWidth - popupWidth; else if (y + popupHeight > screenHeight) y = screenHeight - popupHeight; n = 0; XtSetArg(args[n], XtNx, x); n++; XtSetArg(args[n], XtNy, y); n++; XtSetValues(dataDpy->popupshell, args, n);}/* * Handler procedure called by parse(). * The main function to popup a data display. */void print_handler(output)char *output;{ DataDpyRec *dataDpy; int i, j; if (!output) return; if (!PopupMode) return; PopupMode = False; XDefineCursor(display, XtWindow(toplevel), watch); if (Parent) XDefineCursor(display, XtWindow(Parent->dataDpyWindow), watch); UpdateMessageWindow("Click the label to pop down the data popup",NULL); /* Searches the table for an unused or empty slot */ /* (PW)17OCT91 : test i < dataDpyTableSize first (else segment violation)*/ for (i=0; dataDpyTable && i < dataDpyTableSize && dataDpyTable[i] && dataDpyTable[i]->state == USED ; i++); if (i == dataDpyTableSize) { /* Table full */ dataDpyTableSize += ADD_SIZE; dataDpyTable = (DataDpyRec **) XtRealloc ((void*)dataDpyTable, dataDpyTableSize * sizeof(DataDpyRec *)); for (j=i; j<dataDpyTableSize; j++) dataDpyTable[j] = NULL; } /* Empty slot found, allocate a data structure and initializes some of the fields. */ if (dataDpyTable[i] == NULL) { dataDpyTable[i] = (DataDpyRec *) XtMalloc (sizeof(DataDpyRec)); dataDpyTable[i]->state = EMPTY; dataDpyTable[i]->parent = NULL; dataDpyTable[i]->childlist = NULL; } dataDpy = dataDpyTable[i]; dataDpy->id = i; /* not needed */ dataDpy->buf = XtNewString(output); dataDpy->buflen = strlen(output); BuildLinePos(dataDpy); if (dataDpy->state == EMPTY) CreateDataPopup(dataDpy, Token.mesg); else if (dataDpy->state == UNUSED) UpdateDataPopup(dataDpy, Token.mesg); dataDpy->state = USED; /* mark it used */ if ((dataDpy->parent = Parent)) AppendList(&Parent->childlist, dataDpy); else AppendList(&TopParentList, dataDpy); MovePopup(dataDpy); XtPopup(dataDpy->popupshell, XtGrabNone); if (dataDpy->parent) XUndefineCursor(display, XtWindow(dataDpy->parent->dataDpyWindow)); XUndefineCursor(display, XtWindow(toplevel));}#ifdef GDB#define GOODCHARNAME(c) \ ( (((c) >='a') && ((c) <= 'z')) \ || (((c) >='A') && ((c) <= 'Z')) \ || (((c) >='0') && ((c) <= '9')) \ || ((c) == '_') \ || ((c) == '$') \ )static char *result; /* start of result buffer */static int result_index; /* current index in result buffer */static char *start_txt; /* pointer 1st char of output to parse */static char *curr_txt; /* current pointer in output to parse *//*--------------------------------------------------------------------------+| || Store a character into the buffer. || || Note that characters are added to the buffer RIGHT TO LEFT ! || This is because we parse the output from right to left. || || If the result buffer is full, we set result to "". || |+--------------------------------------------------------------------------*/static void add_char(c)char c;{ if (result_index == 0) /* buffer full */ { *result = 0; return; } if ((c == '.') && (result[result_index] == '.')) return; /* To prevent $1..name for pointers in g++ parents */ result_index--; *(result+result_index) = c;}/*--------------------------------------------------------------------------+| || Store a string into the buffer. || |+--------------------------------------------------------------------------*/static void add_string(s)char *s;{int nbchar; nbchar = strlen(s); /* copy number from last digit */ while (nbchar > 0) add_char(*(s + (--nbchar)));}/*--------------------------------------------------------------------------+| || Store a number into the buffer. || |+--------------------------------------------------------------------------*/static void add_num(number)int number;{char tmpnum[128]; sprintf(tmpnum,"%d",number); add_string(tmpnum);}/*--------------------------------------------------------------------------+| || Init buffer. || || Store a NULL character (as end of string). || |+--------------------------------------------------------------------------*/static void init_result(buffer,buflen)char *buffer;int buflen;{ result = buffer; result_index = buflen; add_char(0); /* end result by null char */}/*--------------------------------------------------------------------------+| || Store the current variable or struct name. || || input : curr_txt points to '=' character, || start_txt points to beginning of the parse string. || || output : curr_txt points to character before 1st character of || name. || || Note : we have to test for the beginning of the parse string, || because add_name() is called also for adding the "$n" name || of the gdb output. || |+--------------------------------------------------------------------------*/static void add_name (){ curr_txt--; /* point before '=' */ while (*curr_txt == ' ') curr_txt--; /* skip spaces */ /* loop over name */ while ((curr_txt >= start_txt) && GOODCHARNAME(*curr_txt)) add_char(*curr_txt--);}/*--------------------------------------------------------------------------+| || Skip all previous characters until corresponding " or ' character. || || input : curr_txt points before ' or " character || || output : curr_txt points before corresponding ' or " character. || |+--------------------------------------------------------------------------*/void search_char(c)char c;{ while(1) { while(c != *(curr_txt--)); /* make sure there is not a '\' just before */ if (*curr_txt != '\\') return; }}/*--------------------------------------------------------------------------+| || Skip all previous characters until previous corresponding '{'. || All "{...}" sequences are skip. || Return the array item number (if applicable) || || input : curr_txt points to string. || || output : curr_txt points to character before '{' || return number of commas || |+--------------------------------------------------------------------------*/static int skip_level(){int nbcommas;char c; nbcommas = 0; while(1) { switch (c = *(curr_txt--)) { case '{' : return nbcommas; case ',' : nbcommas++; break; case '}' : skip_level(); break; case '"' : case '\'' : search_char(c); break; default: break; } }}/*--------------------------------------------------------------------------+| || Function to parse an output of a gdb print from || a pointer (0x...) and return a command line to || print *(0x...) || || input : command line pointer (LINESIZ size), || pointer print output, || pointer 0x... || || output : command line (stored RIGHT justified in commandline) || || example || || start = "$1 = { (struct foo *) 0x1224}" || current points to 0x1224 in start, || || commandline = "print *($1)" || |+--------------------------------------------------------------------------*/char *parse_gdb_print (commandline, start, current)char *commandline;char *start;char *current;{char *begin; start_txt = start; /* in static variables */ curr_txt = current; begin = strchr(start,'='); /* find '=' in "$n =" */ if (!begin) return NULL; init_result(commandline,LINESIZ); add_string(")\n"); while (begin <= curr_txt) { switch (*curr_txt) { case '=': add_name(); /* stop now if we just parsed the '=' in "$n =" */ if (curr_txt >= start_txt) { add_char('.'); skip_level(); } break; case ',': case '{': add_char(']'); add_num(skip_level()); add_char('['); break; default: curr_txt--; } } add_string("print *("); if (debug) fprintf(stderr,"datadpy=%s\n",result+result_index); return result+result_index;}#endif /* GDB */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -