/* * Copyright (c) 1993 by the University of Southern California * * For copying and distribution information, please see the file * . * * The menu API and client were written by Kwynn Buess (buess@isi.edu) */ #include #include "menu.h" #include "config.h" #include #include #include extern char *m_error; static char error_buffer[300]; /* XXX Will have to replace this with the flexible-length general Prospero string handling routines. */ #define ck_fatal_err if ((m_error) != NULL) { fprintf(stderr,"%s",m_error); exit(1);} VLINK set_environ(int argc,char *argv[]) { int err; VLINK vl,vl2,vl3,vl4; VDIR_ST dir_st; VDIR dir = &dir_st; char *err_msg_1 = "\nNo initial directory is available\n\n"; if (argc == 0) { vl = rd_vlink("/MENU"); if (vl != NULL) return vl; #ifdef MENU_DEFAULT_HOST #ifdef MENU_DEFAULT_DIRECTORY vl = vlalloc(); vl->hsoname = stcopy(MENU_DEFAULT_DIRECTORY); vl->host = stcopy(MENU_DEFAULT_HOST); return vl; #endif #endif #ifndef P_SITE_DIRECTORY fprintf(stderr,"%s",err_msg_1); return NULL; #endif #ifndef P_SITE_HOST fprintf(stderr,"%s",err_msg_1); return NULL; #endif vl = vlalloc(); vl->hsoname = stcopy(P_SITE_DIRECTORY); vl->host = stcopy(P_SITE_HOST); vdir_init(dir); if (p_get_dir(vl,P_SITE_MASTER_VSLIST,dir,GVD_FIND,NULL) != PSUCCESS) { fprintf(stderr,"%s",err_msg_1); return NULL; } vllfree(vl); vl2 = dir->links; if (vl2 == NULL) return NULL; if (p_get_dir(vl2,P_PROTOTYPE_VS,dir,GVD_FIND,NULL) != PSUCCESS) { fprintf(stderr,"%s",err_msg_1); return NULL; } /* vllfree(vl2); */ vl3 = dir->links; if (vl3 == NULL) return NULL; if (p_get_dir(vl3,"ROOT",dir,GVD_FIND,NULL) != PSUCCESS) { fprintf(stderr,"%s",err_msg_1); return NULL; } /* vllfree(vl3); */ vl4 = dir->links; if (vl4 == NULL) return NULL; if (p_get_dir(vl4,"MENU",dir,GVD_FIND,NULL) != PSUCCESS) { fprintf(stderr,"%s",err_msg_1); return NULL; } /* vllfree(vl4); */ if (dir->links != NULL) return (dir->links); return NULL; } else if (argc == 1) { vl = rd_vlink(argv[0]); if (vl == NULL) { m_error = error_buffer; sperrmesg(error_buffer,"ERROR: ", 0 ,NULL); return NULL; } return vl; } else if (argc == 3) { argc--;argv++; vl = vlalloc(); vl -> host = stcopy(argv[0]); vl -> hsoname = stcopy(argv[1]); return vl; } return NULL; } void init_menu(MCS *mc,VLINK first_link) { VLINK temp; MCS mcs = (MCS) stalloc(sizeof(struct menu_control_struct));; if (mcs == NULL) { fprintf(stderr,"\nOUT OF MEMORY!!!\n\n"); exit(1); } temp = first_link; if (temp == NULL) { fprintf(stderr,"\nNo initial menu could be found\n\n"); exit(1); } mcs->warning = NULL; *p_warn_string = '\0'; mcs->current = m_get_menu(temp); if (*p_warn_string) mcs->warning = tkappend(p_warn_string, mcs->warning); p_warn_string[0] = '\0'; ck_fatal_err; mcs->earlier = mcs->later = NULL; mcs->name_of_parent = stcopy(m_item_description(temp)); ck_fatal_err; vlfree(temp); (*mc) = mcs; } void get_menu(MCS *mcs,VLINK parent) { MCS new = (MCS) stalloc(sizeof(struct menu_control_struct)); if (new == NULL) { fprintf(stderr,"\nOUT OF MEMORY!!!\n\n"); exit(1); } (*mcs)->later = new; new->earlier = (*mcs); new->name_of_parent = stcopy(m_item_description(parent)); new->later = NULL; new->warning = NULL; *p_warn_string = '\0'; new->current = m_get_menu(parent); if (*p_warn_string) new->warning = tkappend(p_warn_string, new->warning); p_warn_string[0] = '\0'; (*mcs) = new; if (m_error != NULL) { fprintf(stderr,"%s\n",m_error); printf("\n\nRepeating previous menu\n"); m_error = NULL; /* clear error flag */ up_menu(mcs); } } void get_search(MCS *mcs,VLINK parent) { MCS new = (MCS) stalloc(sizeof(struct menu_control_struct)); if (new == NULL) { fprintf(stderr,"\nOUT OF MEMORY!!!\n\n"); exit(1); } (*mcs)->later = new; new->warning = NULL; new->earlier = (*mcs); new->name_of_parent = stcopy(m_item_description(parent)); new->later = NULL; new->warning = NULL; *p_warn_string = '\0'; new->current = open_search(parent); if (*p_warn_string) new->warning = tkappend(p_warn_string, (new)->warning); (*mcs) = new; p_warn_string[0] = '\0'; if (m_error != NULL) { fprintf(stderr,"%s\n",m_error); printf("\n\nRepeating previous menu\n"); m_error = NULL; /* clear error flag */ up_menu(mcs); } } /* Read value from user and return */ int query_choice(MCS *mcs) { printf("\nPress a number to select a menu item, q to Quit"); if (!top_menu(mcs)) printf(", u to go up a menu"); printf(": "); return get_top_level_answer(); /* if (answer[0] == 'q') return -1; if (answer[0] == 'u') return 0 ; */ /* for (cnt=0; (isdigit(answer[cnt])) && (answer[cnt] != '\0') && (answer[cnt]!= '\n') ; cnt++); if (answer[cnt] == '\n') answer[cnt] = '\0'; temp = atoi(answer); if (temp == 0) return -2; */ /* If the answer string got to the end that means that all components were digits and it's a valid number (values that are too high are handled in return_choice(). */ /* if (answer[cnt] == '\0') return atoi(answer); */ /* If it ended because there were no digits, then it's invalid. */ /* else return -2; */ } int top_menu(MCS *mcs) { if ((*mcs)->earlier == NULL) return 1; else return 0; } void up_menu(MCS *mcs) { if ((*mcs)->current != NULL) { vllfree((*mcs)->current); } stfree((*mcs)->name_of_parent); (*mcs) = (*mcs)->earlier; stfree((*mcs)->later); (*mcs)->later = NULL; } void print_current_menu(MCS *mcs) { int cnt = 0; VLINK trans = (*mcs)->current; char *temp; int temp_cl; printf("\n\nMenu for %s\n",(*mcs)->name_of_parent); if ((*mcs)->warning) { TOKEN tk; puts("Got the following warning(s) from Prospero:"); for (tk = (*mcs)->warning; tk; tk = tk->next) puts(tk->token); tkfree((*mcs)->warning); (*mcs)->warning = NULL; } putchar('\n'); while (trans != NULL) { temp = m_item_description(trans); if (!(temp == NULL || trans->linktype == 'I')) { printf("%4d",++cnt); if ((temp_cl = m_class(trans)) == M_CLASS_MENU) printf("> "); else if (temp_cl == M_CLASS_PORTAL) printf("] "); else if (temp_cl == M_CLASS_SEARCH) printf(": "); else printf(". "); printf("%s\n",temp); } trans = trans -> next; } } /* Walks linked list of VLINKS and returns link 'ch' (first is 1) */ VLINK return_choice(int ch,MCS *mcs) { int cnt = 0; VLINK temp = (*mcs)->current; do { if (!(get_item_desc(temp) == NULL || temp->linktype == 'I')) cnt++; if (cnt != ch) temp = temp -> next; } while (cnt != ch && temp != NULL); return temp; } int is_empty(MCS *to_check) { if ((*to_check)->current == NULL) return 1; else return 0; } /* These are not yet implemented; they will soon replace the current calls to stalloc(). */ #if 0 MCS mcsalloc(void) { } void mcsfree(MCS mcs) { } #endif