history.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 2009 by egnite GmbH
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*
  35. * \file gorp/edline/history.c
  36. * \brief Simple edit history.
  37. *
  38. * \verbatim
  39. * $Id$
  40. * \endverbatim
  41. */
  42. #include <gorp/edline.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. /*!
  46. * \addtogroup xgEdLine
  47. */
  48. /*@{*/
  49. #ifndef EDIT_DISABLE_HISTORY
  50. /*!
  51. * \brief Create an editor history table.
  52. *
  53. * \param siz Maximum number of history entries.
  54. *
  55. * \return Pointer to an \ref EDITHISTORY structure on success.
  56. * A NULL pointer is returned in case of an error.
  57. */
  58. EDITHISTORY *EditHistoryCreate(int siz)
  59. {
  60. EDITHISTORY *hist = malloc(sizeof(EDITHISTORY));
  61. if (hist) {
  62. hist->hist_siz = siz;
  63. hist->hist_tab = calloc(siz, sizeof(char *));
  64. if (hist->hist_tab == NULL) {
  65. free(hist);
  66. hist = NULL;
  67. }
  68. }
  69. return hist;
  70. }
  71. /*!
  72. * \brief Create an editor history table.
  73. *
  74. * Releases occupied memory.
  75. *
  76. * \param hist Pointer to an \ref EDITHISTORY structure, obtained by a
  77. * previous call to \ref EditHistoryCreate.
  78. */
  79. void EditHistoryDestroy(EDITHISTORY *hist)
  80. {
  81. int i;
  82. if (hist) {
  83. for (i = 0; i < hist->hist_siz; i++) {
  84. if (hist->hist_tab[i]) {
  85. free(hist->hist_tab[i]);
  86. }
  87. }
  88. free(hist);
  89. }
  90. }
  91. /*!
  92. * \brief Replace the specified history table entry.
  93. *
  94. * \param idx Index in to the history table.
  95. * \param buf Pointer to the string that will replace the existing one.
  96. * \param hist Pointer to an \ref EDITHISTORY structure, obtained by a
  97. * previous call to \ref EditHistoryCreate.
  98. */
  99. void EditHistorySet(EDITHISTORY *hist, int idx, char *buf)
  100. {
  101. if (hist) {
  102. if (idx >= 0 && idx < hist->hist_siz) {
  103. if (hist->hist_tab[idx]) {
  104. free(hist->hist_tab[idx]);
  105. hist->hist_tab[idx] = NULL;
  106. }
  107. if (buf) {
  108. hist->hist_tab[idx] = strdup(buf);
  109. }
  110. }
  111. }
  112. }
  113. /*!
  114. * \brief Retrieve the specified history table entry.
  115. *
  116. * \param idx Index in to the history table.
  117. * \param hist Pointer to an \ref EDITHISTORY structure, obtained by a
  118. * previous call to \ref EditHistoryCreate.
  119. */
  120. int EditHistoryGet(EDITHISTORY *hist, int idx, char *buf, int siz)
  121. {
  122. int rc = 0;
  123. char *cp;
  124. if (hist) {
  125. if (idx >= 0 && idx < hist->hist_siz) {
  126. cp = hist->hist_tab[idx];
  127. if (cp) {
  128. rc = strlen(cp) + 1;
  129. if (buf) {
  130. if (rc > siz) {
  131. rc = siz;
  132. }
  133. memcpy(buf, cp, rc);
  134. }
  135. }
  136. }
  137. }
  138. return rc - 1;
  139. }
  140. /*!
  141. * \brief Insert a new history table entry at the specified position.
  142. *
  143. * All following entries are moved up by 1. If the table is full, then
  144. * the top most entry will be removed.
  145. *
  146. * \param idx Index in to the history table.
  147. * \param buf Pointer to the new string. If it doesn't differ from
  148. * the existing entry, than nothing will be changed.
  149. * \param hist Pointer to an \ref EDITHISTORY structure, obtained by a
  150. * previous call to \ref EditHistoryCreate.
  151. */
  152. void EditHistoryInsert(EDITHISTORY *hist, int idx, char *buf)
  153. {
  154. int i;
  155. if (hist && buf && *buf) {
  156. i = hist->hist_siz - 1;
  157. if (idx >= 0 && idx < i) {
  158. if (hist->hist_tab[idx]) {
  159. /* Make sure we have a new contents. */
  160. if (strcmp(hist->hist_tab[idx], buf)) {
  161. /* Release the entry on top. */
  162. if (hist->hist_tab[i]) {
  163. free(hist->hist_tab[i]);
  164. }
  165. /* Move all entries above the insertion point up. */
  166. while (--i >= idx) {
  167. hist->hist_tab[i + 1] = hist->hist_tab[i];
  168. }
  169. } else {
  170. /* No change. */
  171. return;
  172. }
  173. }
  174. hist->hist_tab[idx] = strdup(buf);
  175. }
  176. }
  177. }
  178. #endif /* EDIT_DISABLE_HISTORY */
  179. /*@}*/