소스 검색

Simplifying parsing and data structure building

• Parsing of stdin was simplified by using conventional stdlib functions
  rather than parsing the stdin byte-by-byte.
• Splited parsing of textual input and building of internal data
  structures into two different functions.
master
phillbush 4 년 전
부모
커밋
a5ddd2cd22
1개의 변경된 파일73개의 추가작업 그리고 76개의 파일을 삭제
  1. +73
    -76
      xmenu.c

+ 73
- 76
xmenu.c 파일 보기

@@ -73,6 +73,7 @@ static void setupdc(void);
static void calcgeom(void); static void calcgeom(void);
static struct Item *allocitem(const char *label, const char *output); static struct Item *allocitem(const char *label, const char *output);
static struct Menu *allocmenu(struct Menu *parent, struct Item *list, unsigned level); static struct Menu *allocmenu(struct Menu *parent, struct Item *list, unsigned level);
static struct Menu * buildmenutree(unsigned level, const char *label, const char *output);
static struct Menu *parsestdin(void); static struct Menu *parsestdin(void);
static void calcmenu(struct Menu *menu); static void calcmenu(struct Menu *menu);
static void grabpointer(void); static void grabpointer(void);
@@ -251,7 +252,7 @@ allocitem(const char *label, const char *output)


if ((item = malloc(sizeof *item)) == NULL) if ((item = malloc(sizeof *item)) == NULL)
err(1, "malloc"); err(1, "malloc");
if (*label == '\0') { if (label == NULL) {
item->label = NULL; item->label = NULL;
item->output = NULL; item->output = NULL;
} else { } else {
@@ -310,96 +311,92 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level)
return menu; return menu;
} }


/* create menus and items from the stdin */ /* build the menu tree */
static struct Menu * static struct Menu *
parsestdin(void) buildmenutree(unsigned level, const char *label, const char *output)
{ {
char *s, buf[BUFSIZ]; static struct Menu *prevmenu = NULL; /* menu the previous item was added to */
char *label, *output; static struct Menu *rootmenu = NULL; /* menu to be returned */
unsigned level = 0; struct Item *curritem = NULL; /* item currently being read */
struct Item *item; /* dummy item for loops */
struct Menu *menu; /* dummy menu for loops */
unsigned i; unsigned i;
struct Item *curritem = NULL; /* item currently being read */
struct Menu *prevmenu = NULL; /* menu the previous item was added to */
struct Item *item; /* dummy item for loops */
struct Menu *menu; /* dummy menu for loops */
struct Menu *rootmenu; /* menu to be returned */

rootmenu = NULL;

while (fgets(buf, BUFSIZ, stdin) != NULL) {
level = 0;
s = buf;

while (*s == '\t') {
level++;
s++;
}


label = output = s; /* create the item */

curritem = allocitem(label, output);
while (*s != '\0' && *s != '\t' && *s != '\n') /* put the item in the menu tree */
s++; if (prevmenu == NULL) { /* there is no menu yet */

menu = allocmenu(NULL, curritem, level);
while (*s == '\t') rootmenu = menu;
*s++ = '\0'; prevmenu = menu;

curritem->prev = NULL;
if (*s != '\0' && *s != '\n') } else if (level < prevmenu->level) { /* item is continuation of a parent menu */
output = s; /* go up the menu tree until find the menu this item continues */

for (menu = prevmenu, i = level;
while (*s != '\0' && *s != '\n') menu != NULL && i != prevmenu->level;
s++; menu = menu->parent, i++)

;
if (*s == '\n') if (menu == NULL)
*s = '\0'; errx(1, "reached NULL menu");

curritem = allocitem(label, output);

if (prevmenu == NULL) { /* there is no menu yet */
menu = allocmenu(NULL, curritem, level);
rootmenu = menu;
prevmenu = menu;
curritem->prev = NULL;
curritem->next = NULL;
} else if (level < prevmenu->level) { /* item is continuation of a parent menu*/
for (menu = prevmenu, i = level;
menu != NULL && i < prevmenu->level;
menu = menu->parent, i++)
;

if (menu == NULL)
errx(1, "reached NULL menu");


for (item = menu->list; item->next != NULL; item = item->next) /* find last item in the new menu */
; for (item = menu->list; item->next != NULL; item = item->next)
;


item->next = curritem; prevmenu = menu;
item->next = curritem;
curritem->prev = item;
} else if (level == prevmenu->level) { /* item is a continuation of current menu */
/* find last item in the previous menu */
for (item = prevmenu->list; item->next != NULL; item = item->next)
;


curritem->prev = item; item->next = curritem;
curritem->next = NULL; curritem->prev = item;
} else if (level > prevmenu->level) { /* item begins a new menu */
menu = allocmenu(prevmenu, curritem, level);


prevmenu = menu; /* find last item in the previous menu */
} else if (level == prevmenu->level) { /* item is a continuation of current menu */ for (item = prevmenu->list; item->next != NULL; item = item->next)
for (item = prevmenu->list; item->next != NULL; item = item->next) ;
;
item->next = curritem;


curritem->prev = item; prevmenu = menu;
curritem->next = NULL; menu->caller = item;
item->submenu = menu;
curritem->prev = NULL;
}


} else if (level > prevmenu->level) { /* item begins a new menu */ return rootmenu;
menu = allocmenu(prevmenu, curritem, level); }


for (item = prevmenu->list; item->next != NULL; item = item->next) /* create menus and items from the stdin */
; static struct Menu *
parsestdin(void)
{
struct Menu *rootmenu;
char *s, buf[BUFSIZ];
char *label, *output;
unsigned level = 0;


item->submenu = menu; while (fgets(buf, BUFSIZ, stdin) != NULL) {
menu->caller = item; /* get the indentation level */
level = strspn(buf, "\t");


curritem->prev = NULL; /* get the label */
curritem->next = NULL; s = level + buf;
label = strtok(s, "\t\n");


prevmenu = menu; /* get the output */
output = strtok(NULL, "\n");
if (output == NULL) {
output = label;
} else {
while (*output == '\t')
output++;
} }

rootmenu = buildmenutree(level, label, output);
} }


return rootmenu; return rootmenu;


||||||
x
 
000:0
불러오는 중...
취소
저장