您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

menu.c 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /** @file
  25. *
  26. * Menu selection
  27. *
  28. */
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <assert.h>
  32. #include <ipxe/list.h>
  33. #include <ipxe/menu.h>
  34. /** List of all menus */
  35. static LIST_HEAD ( menus );
  36. /**
  37. * Create menu
  38. *
  39. * @v name Menu name, or NULL
  40. * @v title Menu title, or NULL
  41. * @ret menu Menu, or NULL on failure
  42. */
  43. struct menu * create_menu ( const char *name, const char *title ) {
  44. size_t name_len;
  45. size_t title_len;
  46. size_t len;
  47. struct menu *menu;
  48. char *name_copy;
  49. char *title_copy;
  50. /* Destroy any existing menu of this name */
  51. menu = find_menu ( name );
  52. if ( menu )
  53. destroy_menu ( menu );
  54. /* Use empty title if none given */
  55. if ( ! title )
  56. title = "";
  57. /* Allocate menu */
  58. name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
  59. title_len = ( strlen ( title ) + 1 /* NUL */ );
  60. len = ( sizeof ( *menu ) + name_len + title_len );
  61. menu = zalloc ( len );
  62. if ( ! menu )
  63. return NULL;
  64. name_copy = ( ( void * ) ( menu + 1 ) );
  65. title_copy = ( name_copy + name_len );
  66. /* Initialise menu */
  67. if ( name ) {
  68. strcpy ( name_copy, name );
  69. menu->name = name_copy;
  70. }
  71. strcpy ( title_copy, title );
  72. menu->title = title_copy;
  73. INIT_LIST_HEAD ( &menu->items );
  74. /* Add to list of menus */
  75. list_add_tail ( &menu->list, &menus );
  76. DBGC ( menu, "MENU %s created with title \"%s\"\n",
  77. menu->name, menu->title );
  78. return menu;
  79. }
  80. /**
  81. * Add menu item
  82. *
  83. * @v menu Menu
  84. * @v label Label, or NULL
  85. * @v text Text, or NULL
  86. * @v shortcut Shortcut key
  87. * @v is_default Item is the default item
  88. * @ret item Menu item, or NULL on failure
  89. */
  90. struct menu_item * add_menu_item ( struct menu *menu, const char *label,
  91. const char *text, int shortcut,
  92. int is_default ) {
  93. size_t label_len;
  94. size_t text_len;
  95. size_t len;
  96. struct menu_item *item;
  97. char *label_copy;
  98. char *text_copy;
  99. /* Use empty text if none given */
  100. if ( ! text )
  101. text = "";
  102. /* Allocate item */
  103. label_len = ( label ? ( strlen ( label ) + 1 /* NUL */ ) : 0 );
  104. text_len = ( strlen ( text ) + 1 /* NUL */ );
  105. len = ( sizeof ( *item ) + label_len + text_len );
  106. item = zalloc ( len );
  107. if ( ! item )
  108. return NULL;
  109. label_copy = ( ( void * ) ( item + 1 ) );
  110. text_copy = ( label_copy + label_len );
  111. /* Initialise item */
  112. if ( label ) {
  113. strcpy ( label_copy, label );
  114. item->label = label_copy;
  115. }
  116. strcpy ( text_copy, text );
  117. item->text = text_copy;
  118. item->shortcut = shortcut;
  119. item->is_default = is_default;
  120. /* Add to list of items */
  121. list_add_tail ( &item->list, &menu->items );
  122. return item;
  123. }
  124. /**
  125. * Destroy menu
  126. *
  127. * @v menu Menu
  128. */
  129. void destroy_menu ( struct menu *menu ) {
  130. struct menu_item *item;
  131. struct menu_item *tmp;
  132. /* Remove from list of menus */
  133. list_del ( &menu->list );
  134. /* Free items */
  135. list_for_each_entry_safe ( item, tmp, &menu->items, list ) {
  136. list_del ( &item->list );
  137. free ( item );
  138. }
  139. /* Free menu */
  140. free ( menu );
  141. }
  142. /**
  143. * Find menu
  144. *
  145. * @v name Menu name, or NULL
  146. * @ret menu Menu, or NULL if not found
  147. */
  148. struct menu * find_menu ( const char *name ) {
  149. struct menu *menu;
  150. list_for_each_entry ( menu, &menus, list ) {
  151. if ( ( menu->name == name ) ||
  152. ( strcmp ( menu->name, name ) == 0 ) ) {
  153. return menu;
  154. }
  155. }
  156. return NULL;
  157. }