00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #include <stdlib.h>
00027 #include <errno.h>
00028 #include <string.h>
00029 #include "buffer.h"
00030 #include "buffer_internal.h"
00031 #include "buffer_util.h"
00032 #include "buffer_event.h"
00033 #include "type_limits.h"
00034 
00035 #include "debug.h"
00036 
00037 
00038 #pragma GCC visibility push(default)
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 int bless_buffer_can_undo(bless_buffer_t *buf, int *can_undo)
00050 {
00051     if (buf == NULL || can_undo == NULL)
00052         return_error(EINVAL);
00053 
00054     struct list_node *first = list_head(buf->undo_list)->next;
00055 
00056     *can_undo = !(first->next == first);
00057 
00058     return 0;
00059 }
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 int bless_buffer_can_redo(bless_buffer_t *buf, int *can_redo)
00070 {
00071     if (buf == NULL || can_redo == NULL)
00072         return_error(EINVAL);
00073 
00074     struct list_node *first = list_head(buf->redo_list)->next;
00075 
00076     *can_redo = !(first->next == first);
00077 
00078     return 0;
00079 }
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 int bless_buffer_get_size(bless_buffer_t *buf, off_t *size)
00090 {
00091     if (buf == NULL || size == NULL)
00092         return_error(EINVAL);
00093 
00094     return segcol_get_size(buf->segcol, size);
00095 }
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 int bless_buffer_set_option(bless_buffer_t *buf, bless_buffer_option_t opt,
00107         char *val)
00108 {
00109     if (buf == NULL || opt >= BLESS_BUF_SENTINEL)
00110         return_error(EINVAL);
00111 
00112     switch (opt) {
00113         case BLESS_BUF_TMP_DIR:
00114             if (val == NULL)
00115                 return_error(EINVAL);
00116             else {
00117                 char *dup = strdup(val);
00118                 if (dup == NULL)
00119                     return_error(ENOMEM);
00120 
00121                 
00122                 if (buf->options->tmp_dir != NULL)
00123                     free(buf->options->tmp_dir);
00124                 buf->options->tmp_dir = dup;
00125             }
00126             break;
00127 
00128         case BLESS_BUF_UNDO_LIMIT:
00129             if (val == NULL)
00130                 return_error(EINVAL);
00131             else if (!strcmp(val, "infinite")) {
00132                 char *dup = strdup(val);
00133                 if (dup == NULL)
00134                     return_error(ENOMEM);
00135 
00136                 
00137                 if (buf->options->undo_limit_str != NULL)
00138                     free(buf->options->undo_limit_str);
00139 
00140                 buf->options->undo_limit_str = dup;
00141                 buf->options->undo_limit = __MAX(size_t);
00142             }
00143             else {
00144                 char *endptr;
00145                 size_t limit = strtoul(val, &endptr, 10);
00146                 if (*val == '\0' || *endptr != '\0')
00147                     return_error(EINVAL);
00148 
00149                 char *dup = strdup(val);
00150                 if (dup == NULL)
00151                     return_error(ENOMEM);
00152 
00153                 
00154                 if (buf->options->undo_limit_str != NULL)
00155                     free(buf->options->undo_limit_str);
00156 
00157                 buf->options->undo_limit_str = dup;
00158                 buf->options->undo_limit = limit;
00159             }
00160 
00161             
00162 
00163 
00164 
00165             undo_list_enforce_limit(buf, 0);
00166             action_list_clear(buf->redo_list);
00167             buf->redo_list_size = 0;
00168 
00169             break;
00170 
00171         case BLESS_BUF_UNDO_AFTER_SAVE:
00172             if (val == NULL || (strcmp(val, "always") && strcmp(val, "never")
00173                     && strcmp(val, "best_effort")))
00174                 return_error(EINVAL);
00175             else {
00176                 char *dup = strdup(val);
00177                 if (dup == NULL)
00178                     return_error(ENOMEM);
00179 
00180                 
00181                 if (buf->options->undo_after_save != NULL)
00182                     free(buf->options->undo_after_save);
00183                 buf->options->undo_after_save = dup;
00184             }
00185             break;
00186         default:
00187             break;
00188     }
00189 
00190     return 0;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 int bless_buffer_get_option(bless_buffer_t *buf, char **val,
00206         bless_buffer_option_t opt)
00207 {
00208     if (buf == NULL || opt >= BLESS_BUF_SENTINEL)
00209         return_error(EINVAL);
00210 
00211     switch (opt) {
00212         case BLESS_BUF_TMP_DIR:
00213             *val = buf->options->tmp_dir;
00214             break;
00215 
00216         case BLESS_BUF_UNDO_LIMIT:
00217             *val = buf->options->undo_limit_str;
00218             break;
00219 
00220         case BLESS_BUF_UNDO_AFTER_SAVE:
00221             *val = buf->options->undo_after_save;
00222             break;
00223 
00224         default:
00225             *val = NULL;
00226             break;
00227     }
00228 
00229     return 0;
00230 }
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 int bless_buffer_set_event_callback(bless_buffer_t *buf,
00245         bless_buffer_event_func_t *func, void *user_data)
00246 {
00247     if (buf == NULL)
00248         return_error(EINVAL);
00249 
00250     buf->event_func = func;
00251     buf->event_user_data = user_data;
00252 
00253     return 0;
00254 }
00255 
00256 #pragma GCC visibility pop
00257