/* * stack.c - does the handling of stack functions * * written by matthew green * * copyright (C) 1993. */ #ifndef lint static char rcsid[] = "@(#)$Id: stack.c,v 1.13 1994/10/14 23:14:23 mrg Stab $"; #endif #include "irc.h" #include "stack.h" #include "window.h" #include "hook.h" #include "ircaux.h" #include "output.h" #include "list.h" static OnStack *on_stack = NULL; static AliasStack *alias_stack = NULL; static AliasStack *assign_stack = NULL; static SetStack *set_stack = NULL; static AliasStack *alias_get __P((char *, int)); static AliasStack *alias_stack_find __P((char *, int)); static void alias_stack_add __P((AliasStack *, int)); static void do_stack_on(type, args) int type; char *args; { char foo[4]; int len, cnt, i, which = 0; Hook *list; NumericList *nhook, *nptr, *ntmp; if (!on_stack && (type == STACK_POP || type == STACK_LIST)) { say("ON stack is empty!"); return; } if (!args || !*args) { say("Missing event type for STACK ON"); return; } len = strlen(args); for (cnt = 0, i = 0; i < NUMBER_OF_LISTS; i++) { if (!my_strnicmp(args, hook_functions[i].name, len)) { if (strlen(hook_functions[i].name) == len) { cnt = 1; which = i; break; } else { cnt++; which = i; } } else if (cnt) break; } if (!cnt) { if (is_number(args)) { which = atoi(args); if (which < 1 || which > 999) { say("Numerics must be between 001 and 999"); return; } which = -which; } else { say("No such ON function: %s", args); return; } } if (which < 0) { sprintf(foo, "%3.3u", -which); if ((nhook = (NumericList *) find_in_list(&numeric_list, foo, 0)) != NULL) list = nhook->list; else list = NULL; } else list = hook_functions[which].list; if (type == STACK_PUSH) { OnStack *new; if (list == NULL) { say("The ON %s list is empty", args); return; } new = (OnStack *) new_malloc(sizeof(OnStack)); new->next = on_stack; on_stack = new; new->which = which; new->list = list; if (which < 0) { if (nhook == numeric_list) { numeric_list = nhook->next; new_free(&nhook->name); new_free(&nhook); return; } for (nptr = numeric_list; nptr; ntmp = nptr, nptr = nptr->next) { if (nptr == nhook) { ntmp->next = nptr->next; new_free(&nptr->name); new_free(&nptr); return; } } } else hook_functions[which].list = NULL; return; } else if (type == STACK_POP) { OnStack *p, *tmp; for (p = on_stack; p; tmp = p, p = p->next) { if (p->which == which) { if (p == on_stack) on_stack = p->next; else tmp->next = p->next; break; } } if (!p) { say("No %s on the stack", args); return; } if (which < 0 && nhook || hook_functions[which].list) remove_hook(which, NULL, 0, 0, 1); /* free hooks */ if (which < 0) { if ((nptr = (NumericList *) find_in_list(&numeric_list, foo, 0)) == NULL) { nptr = (NumericList *) new_malloc(sizeof(NumericList)); nptr->name = NULL; nptr->list = p->list; malloc_strcpy(&nptr->name, foo); add_to_list(&numeric_list, nptr); } else add_to_list(&numeric_list->list, p->list); } else hook_functions[which].list = p->list; return; } else if (type == STACK_LIST) { int slevel = 0; OnStack *osptr; for (osptr = on_stack; osptr; osptr = osptr->next) if (osptr->which == which) { Hook *hptr; slevel++; say("Level %d stack", slevel); for (hptr = osptr->list; hptr; hptr = hptr->next) show_hook(hptr, args); } if (!slevel) say("The STACK ON %s list is empty", args); return; } say("Unknown STACK ON type ??"); } static void do_stack_alias(type, args, which) int type; char *args; int which; { char *name; AliasStack *aptr, **aptrptr; if (which == STACK_DO_ALIAS) { name = "ALIAS"; aptrptr = &alias_stack; } else { name = "ASSIGN"; aptrptr = &assign_stack; } if (!*aptrptr && (type == STACK_POP || type == STACK_LIST)) { say("%s stack is empty!", name); return; } if (STACK_PUSH == type) { aptr = alias_get(args, which); if ((AliasStack *) 0 == aptr) { say("No such %s %s", name, args); return; } if (aptrptr) aptr->next = *aptrptr; *aptrptr = aptr; return; } if (STACK_POP == type) { aptr = alias_stack_find(args, which); if ((AliasStack *) 0 == aptr) { say("%s is not on the %s stack!", args, name); return; } alias_stack_add(aptr, which); return; } if (STACK_LIST == type) { say("stack list is not implimented yet"); return; } say("Unknown STACK type ??"); } static void do_stack_set(type, args) int type; char *args; { } /* * alias_get: this returns a point to an `AliasStack' structure that * has be extracted from the current aliases, and removed from that * list. */ static AliasStack* alias_get(args, which) char *args; int which; { return (AliasStack *) 0; } /* * alias_stack_find: this returns the pointer to the struct with the * most recent alias for `args' in the stack. */ static AliasStack* alias_stack_find(args, which) char *args; int which; { return (AliasStack *) 0; } /* * alias_stack_add: this adds `aptr' to the alias/assign stack. */ static void alias_stack_add(aptr, which) AliasStack *aptr; int which; { return; } extern void stackcmd(command, args) char *command, *args; { char *arg; int len, type; if ((arg = next_arg(args, &args)) != NULL) { len = strlen(arg); if (!my_strnicmp(arg, "PUSH", len)) type = STACK_PUSH; else if (!my_strnicmp(arg, "POP", len)) type = STACK_POP; else if (!my_strnicmp(arg, "LIST", len)) type = STACK_LIST; else { say("%s is unknown stack type", arg); return; } } else { say("Need operation for STACK"); return; } if ((arg = next_arg(args, &args)) != NULL) { len = strlen(arg); if (!my_strnicmp(arg, "ON", len)) do_stack_on(type, args); else if (!my_strnicmp(arg, "ALIAS", len)) do_stack_alias(type, args, STACK_DO_ALIAS); else if (!my_strnicmp(arg, "ASSIGN", len)) do_stack_alias(type, args, STACK_DO_ASSIGN); else if (!my_strnicmp(arg, "SET", len)) do_stack_set(type, args); else { say("%s is not a valid STACK type"); return; } } else { say("Need stack type for STACK"); return; } }