예제 #1
0
int main()
{
  list_t *data = NULL;
  char *item1 = NULL;
  char *item2 = NULL;
  char *item3 = NULL;
  char *item4 = NULL;

  SIGCATCH_INIT

  CALLOC(data, 1, sizeof(list_t));

  /** init list_t #1 */
  list_item_add(data, "test",   0);
  list_item_add(data, "string", 0);
  list_item_add(data, "ring",   0);
  assert(data->len == 17);
  assert(memcmp(data->buf, "test\0string\0ring\0", 17) == 0);

  item1 = list_item_search(data, "test");
  assert(item1 != NULL);
  assert(data->buf == item1);

  item2 = list_item_search(data, "string");
  assert(item2 != NULL);

  item3 = list_item_search(data, "ring");
  assert(item3 != NULL);
  assert(item3 != item2);

  item4 = list_item_search(data, "no such item");
  assert(item4 == NULL);

  return 0;
}
예제 #2
0
int main()
{
  int ret = 0;
  list_t terms;
  search_t search;

  SIGCATCH_INIT

  memset(&terms, 0x0, sizeof(list_t));
  memset(&search, 0x0, sizeof(search_t));

  /* simple match */
  list_item_add(&terms, "alice", 0);
  list_item_add(&terms, "+mary", 0);
  list_item_add(&terms, "-bob", 0);

  ret = search_parse_terms(&search, &terms);
  assert(ret == 0);

  /* motto: nobody loves bob */
  assert(search_match_exact(&search, "test1 test2 test3") == 0);
  assert(search_match_exact(&search, " alice mary ") == 1);
  assert(search_match_exact(&search, " alice rose ") == 0);
  assert(search_match_exact(&search, " alice mary bob ") == 0);
  assert(search_match_exact(&search, " alice rosemary ") == 0);
  assert(search_match_exact(&search, " alice rosemary bob ") == 0);
  assert(search_match_exact(&search, " alice mary robert ") == 1);
  assert(search_match_exact(&search, " malice rosemary robert ") == 0);

  list_clear(&terms);
  search_free(&search);

  return 0;
}
예제 #3
0
int main()
{
  list_t *data = NULL;
  int ret = 0;

  SIGCATCH_INIT

  CALLOC(data, 1, sizeof(list_t));

  /** add first item, test calloc() */
  ret = list_item_add(data, "test1", 0);
  assert(ret == 0);
  assert(data->len == 6);
  assert(memcmp(data->buf, "test1\0", 6) == 0);

  /** add second item */
  list_item_add(data, "test2", 0);
  assert(ret == 0);
  assert(data->len == 12);
  assert(memcmp(data->buf, "test1\0test2\0", 12) == 0);

  list_clear(data);
  data->buf = calloc(10, sizeof(char));
  data->len = 0;
  data->size = 10;
  /** test buffer extending  */
  list_item_add(data, "very long string with spaces", 0);
  assert(data->size >= data->len);
  assert(data->len == 29);
  assert(memcmp(data->buf, "very long string with spaces", 29) == 0);

  return 0;
}
예제 #4
0
int main()
{
  int ret = 0;
  list_t terms;
  search_t search;

  SIGCATCH_INIT

  memset(&terms, 0x0, sizeof(list_t));
  memset(&search, 0x0, sizeof(search_t));

  /* simple match */
  list_item_add(&terms, "alice", 0);
  list_item_add(&terms, "mary", 0);

  ret = search_parse_terms(&search, &terms);
  assert(ret == 0);

  assert(search_match_substr(&search, "test1 test2 test3") == 0);
  assert(search_match_substr(&search, " alice mary ") == 1);
  assert(search_match_substr(&search, " alice rose ") == 0);
  assert(search_match_substr(&search, " alice mary bob") == 1);
  assert(search_match_substr(&search, " alice rosemary ") == 1);
  assert(search_match_substr(&search, " alice rosemary bob ") == 1);

  list_clear(&terms);
  search_free(&search);

  /* more complex examples */
  list_item_add(&terms, "alice", 0);
  assert(search_parse_terms(&search, &terms) == 0);
  assert(search_match_substr(&search, " alice ") == 1);
  assert(search_match_substr(&search, "malice") == 1);
  assert(search_match_substr(&search, " mary ") == 0);
  list_clear(&terms);
  search_free(&search);

  list_item_add(&terms, "~mary", 0);
  assert(search_parse_terms(&search, &terms) == 0);
  assert(search_match_substr(&search, " alice ") == 1);
  assert(search_match_substr(&search, " mary ") == 0);
  assert(search_match_substr(&search, "mary") == 0);
  assert(search_match_substr(&search, "rosemary") == 0);
  assert(search_match_substr(&search, " rosemary ") == 0);
  list_clear(&terms);
  search_free(&search);

  return 0;
}
예제 #5
0
파일: db.c 프로젝트: AdUser/xa-tags
static void
_db_stats_query(list_t *stats, const char *query, const char *desc)
{
  sqlite3_stmt *stmt = NULL;
  char *buf = NULL;
  unsigned int value = 0;
  size_t len = 0;

  if ((len = strlen(query)) == 0)
    return;

  if (sqlite3_prepare_v2(db_conn, query, len, &stmt, NULL) != SQLITE_OK)
    msg(msg_error, COMMON_ERR_FMTN, MSG_D_FAILPREPARE, sqlite3_errmsg(db_conn));

  if (sqlite3_step(stmt) != SQLITE_ROW)
    msg(msg_warn, MSG_D_FAILEXEC, sqlite3_errmsg(db_conn));

  value = sqlite3_column_int(stmt, 0);
  sqlite3_finalize(stmt);

  CALLOC(buf, PATH_MAX, sizeof(char));
  len = snprintf(buf, PATH_MAX, STAT_MSG_FMT, value, desc);
  list_item_add(stats, buf, len);
  FREE(buf);
}
예제 #6
0
파일: db.c 프로젝트: AdUser/xa-tags
/** return values:
 * 0 - all ok
 * 1 - more data expected
 * 2 - error
 */
int
db_tags_find(const char *str, query_limits_t *lim, list_t *results)
{
#ifdef UNIQ_TAGS_LIST
  sqlite3_stmt *stmt = NULL;
  char buf[PATH_MAX]; /* not exactly 'path', but size should be reasonable */
  char *p = NULL;
  size_t len = 0;
  int ret = 0;

  ASSERT(str != NULL && lim != NULL && results != NULL, MSG_M_NULLPTR);

  len = strlen(SQL_T_FIND);
  if (sqlite3_prepare_v2(db_conn, SQL_T_FIND, len, &stmt, NULL) != SQLITE_OK)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILPREPARE, sqlite3_errmsg(db_conn));
      return 2;
    }

  if (results != NULL)
    list_clear(results);

  strncpy(buf, str, PATH_MAX);
  for (p = buf; *p != '\0'; p++)
    if (*p == '*') *p = '%';

  sqlite3_bind_text(stmt, 1, buf, len, SQLITE_TRANSIENT);
  sqlite3_bind_int(stmt, 2, lim->limit);
  sqlite3_bind_int64(stmt, 3, lim->offset);

  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
    {
      len = snprintf(buf, PATH_MAX, "%s", (char *) sqlite3_column_text(stmt, 0));
      list_item_add(results, buf, len);
      lim->offset++;
    }

  if (ret != SQLITE_DONE)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILEXEC, sqlite3_errmsg(db_conn));
      sqlite3_finalize(stmt);
      list_clear(results);
      return 2;
    }

  sqlite3_finalize(stmt);

  return (results->items == MAX_QUERY_LIMIT) ? 1 : 0;
#else
  return 0;
#endif
}
예제 #7
0
static void easy_menu_loop(menu_item_t* menu, char* desc)
{
    list_dst* menu_ptr;
    menu_ptr = list_init();
    if (NULL == menu_ptr)
    {
        error_exit(3, "不能创建菜单控件");
    }
    list_props_set(menu_ptr , list_menu_property);
    int menu_count;
    for (menu_count = 0;; ++menu_count)
    {
        if (NULL == menu[menu_count].menu_desc)
            break;
        list_item_add(menu_ptr, menu[menu_count].menu_desc);
    }

    int32 ret;
    dis_mod_set(MAIN_DISP, INPUT_HZ_FONT, INPUT_ASC_FONT);
    while (1)
    {
        CLEAR_SCREEN;
        printf_str(MAIN_DISP, DISP_X_COOR, DISP_Y_COOR, ">", 1);
        printf_str(MAIN_DISP, DISP_X_COOR + 9, DISP_Y_COOR, desc, 1);
        line(MAIN_DISP , DISP_X_COOR, DISP_X_COOR + 28, DISP_X_COOR + 140, DISP_X_COOR + 28, 1);
        line(MAIN_DISP , DISP_X_COOR, DISP_X_COOR + 30, DISP_X_COOR + 140, DISP_X_COOR + 30, 1);
        list_show(MAIN_DISP, menu_ptr);
        lcd_160_upd();

        ret = list_key_manege(MAIN_DISP, menu_ptr, lcd_160_upd);
        if (ret < 0)
        {
            list_exit(menu_ptr) ;
            return ;
        }
        if (ret < menu_count)
        {
            menu[ret].func();
            dis_mod_set(MAIN_DISP, INPUT_HZ_FONT, INPUT_ASC_FONT);
        }
    }

}
예제 #8
0
int main()
{
  int ret = 0;
  list_t terms;
  search_t search;

  SIGCATCH_INIT

  memset(&terms, 0x0, sizeof(list_t));
  memset(&search, 0x0, sizeof(search_t));

  list_item_add(&terms, "fred", 0);
  list_item_add(&terms, "~velma", 0);
  list_item_add(&terms, "+dafna", 0);
  list_item_add(&terms, "-shaggy", 0);
#ifdef REGEX_SEARCH
  list_item_add(&terms, "-/[ck]tulhu/", 0);
  list_item_add(&terms, "/nyan_cat/i", 0);
#endif

  ret = search_parse_terms(&search, &terms);
  assert(ret == 0);
  assert(search.substr.items == 3);
  assert(search.exact.items  == 2);
  assert(memcmp(search.substr.buf, "+fred\0-velma\0+dafna\0", 6 + 7 + 7) == 0);
  assert(memcmp(search.exact.buf,  "+ dafna \0- shaggy \0", 9 + 10) == 0);
#ifdef REGEX_SEARCH
  assert(search.regex_cnt == 2);
  assert(search.regex_neg[0] == true);
  assert(search.regex_neg[1] == false);
  assert(search.regex_neg[2] == false);
  assert(memcmp(&search.regexps[0], &search.regexps[2], sizeof(regex_t)) != 0);
  assert(memcmp(&search.regexps[1], &search.regexps[2], sizeof(regex_t)) != 0);
#endif

  search_free(&search);

  return 0;
}
예제 #9
0
int
main(int argc, char **argv)
{
  int ret = 0;
  list_t files;
  struct stat st;
  char opt = 0;
  char *tags = NULL;
  char *item = NULL;
  void (*handler)(const char *, const char *) = NULL;

  memset(&files, 0, sizeof(list_t));

#ifdef HAVE_GETTEXT
  setlocale (LC_ALL, "");
  bindtextdomain(PROGNAME, LOCALEDIR);
  textdomain(PROGNAME);
#endif

  if (argc < 2)
    usage(EXIT_FAILURE);

  while ((opt = getopt(argc, argv, "rvqh" "clL" "a:d:s:" "f:")) != -1)
    switch (opt)
      {
        /* operations */
        case 'a' : handler = &_handle_tag_add; tags = optarg; break;
        case 'd' : handler = &_handle_tag_del; tags = optarg; break;
        case 's' : handler = &_handle_tag_set; tags = optarg; break;
        case 'c' : handler = &_handle_tag_clr; break;
        case 'l' : handler = &_handle_tag_lst; break;
        case 'L' : handler = &_handle_file_dirlist; break;
        case 'f' : handler = &_handle_search_by_tag; tags = optarg; flags |= F_RECURSE; break;
        /* options */
        case 'v' : verbosity = log_extra; break;
        case 'q' : verbosity = log_quiet; break;
        case 'r' : flags |= F_RECURSE; break;
        case 'h' : usage(EXIT_SUCCESS); break;
        default  : usage(EXIT_FAILURE); break;
      }

  for (; optind < argc; optind++)
    {
      errno = 0;
      if (stat(argv[optind], &st) == 0)
        list_item_add(&files, argv[optind], 0);
      else
        printf(COMMON_ERR_FMTN, argv[optind], strerror(errno));
    }

  if (files.items < 1)
    usage(EXIT_FAILURE);

  /* init */
  while ((ret = list_items_walk(&files, &item)) > 0)
    (flags & F_RECURSE) ? ftw_cb(item, tags, handler) : handler(item, tags);

  list_clear(&files);
  FREE(search);

  exit(EXIT_SUCCESS);
}
예제 #10
0
파일: db.c 프로젝트: AdUser/xa-tags
/** return values:
 * 0 - all ok
 * 1 - more data expected
 * 2 - error
 */
int
db_file_search_tag(const search_t *search, query_limits_t *lim, list_t *results,
                   int (*cb)(uuid_t, const char *, const char *))
{
  sqlite3_stmt *stmt;
  size_t len = 0;
  int ret = 0;
  int rows = 0;
  int matches = 0;
  char buf[PATH_MAX] = { 0 };
  char *fts_query = NULL;
  uuid_t uuid = 0;
  char *filename = NULL;
  char *tags = NULL;

  ASSERT(search != NULL && lim != NULL && (results != NULL || cb != NULL), MSG_M_NULLPTR);

  len = strlen(SQL_T_SEARCH);
  if (sqlite3_prepare_v2(db_conn, SQL_T_SEARCH, len, &stmt, NULL) != SQLITE_OK)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILPREPARE, sqlite3_errmsg(db_conn));
      return 2;
    }

  if (results != NULL)
    list_clear(results);

  fts_query = _db_get_fts_query(search);

  do /* loop, until we get 'limit' items or lesser than 'limit' rows from query */
    {
      sqlite3_bind_text(stmt, 1, fts_query, -1, SQLITE_TRANSIENT);
      sqlite3_bind_int(stmt,   2, lim->limit);
      sqlite3_bind_int64(stmt, 3, lim->offset);

      for (rows = 0, matches = 0; (ret = sqlite3_step(stmt)) == SQLITE_ROW;)
        {
          rows++;
          uuid     = (uuid_t) sqlite3_column_int64(stmt, 0);
          filename = (char *) sqlite3_column_text(stmt, 1);
          tags     = (char *) sqlite3_column_text(stmt, 2);
          /* NOTE: we already filter this by FTS query
          if (search_match_substr(search, tags) < 1)
            continue;
          */
          if (search_match_exact(search, tags) < 1)
            continue;
#ifdef REGEX_SEARCH
          if (search_match_regex(search, tags) < 1)
            continue;
#endif
          matches++;

          if (results != NULL)
            {
              len = snprintf(buf, PATH_MAX, "%s", filename);
              list_item_add(results, buf, len);
            }

          if (cb != NULL)
            cb(uuid, filename, tags);

            /* NOTE: if we simple wait until 'for' loop ends,     *
             * number of items in result will float around limit. */
          if (matches == lim->limit)
            break;
        }
      lim->offset += rows;
      sqlite3_reset(stmt);
      sqlite3_clear_bindings(stmt);
    }
  while (matches < lim->limit && rows == lim->limit);
  FREE(fts_query);

  if (ret != SQLITE_DONE && ret != SQLITE_ROW)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILEXEC, sqlite3_errmsg(db_conn));
      if (results != NULL)
        list_clear(results);
      sqlite3_finalize(stmt);
      return 2;
    }

  if (results != NULL)
    {
      if (results->items > 1)
        results->flags |= LIST_MULTI;
      results->type = LIST_L_FILES;
    }

  sqlite3_finalize(stmt);

  return (matches == lim->limit) ? 1 : 0;
}
예제 #11
0
파일: db.c 프로젝트: AdUser/xa-tags
/**
 * NOTE: 'str' may contain '*' chars, if you want fuzzy search
 */
int
db_file_search_path(const char *str, query_limits_t *lim, list_t *results,
                    int (*cb)(const char *, const uuid_t *))
{
  sqlite3_stmt *stmt = NULL;
  uuid_t uuid = 0;
  char *path = NULL;
  size_t len = 0;
  int ret = 0;
  int rows = 0;
  char buf[PATH_MAX + UUID_CHAR_LEN + 3] = { 0 };

  ASSERT(str != NULL && lim != NULL && (results != NULL || cb != NULL), MSG_M_NULLPTR);

  len = strlen(SQL_F_SEARCH);
  if (sqlite3_prepare_v2(db_conn, SQL_F_SEARCH, len, &stmt, NULL) != SQLITE_OK)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILPREPARE, sqlite3_errmsg(db_conn));
      return 2;
    }

  if (results != NULL)
    list_clear(results);

  strncpy(buf, str, PATH_MAX + 1);
  len = strlen(buf);
  while (len --> 0)
    if (buf[len] == '*')
      buf[len] = '%';

  sqlite3_bind_text(stmt, 1, buf, -1, SQLITE_TRANSIENT);
  sqlite3_bind_int(stmt, 2, lim->limit);
  sqlite3_bind_int64(stmt, 3, lim->offset);

  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
    {
      rows++;
      uuid = (uuid_t) sqlite3_column_int64(stmt, 0);
      path = (char *) sqlite3_column_text(stmt, 2);

      if (results != NULL)
        {
          len = snprintf_m_uuid_file(buf, PATH_MAX + UUID_CHAR_LEN + 3,
                                     &uuid, (char *) sqlite3_column_text(stmt, 2));
          list_item_add(results, buf, len);
        }

      if (cb != NULL)
        cb(path, &uuid);
    }
  lim->offset += rows;

  if (ret != SQLITE_DONE)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILEXEC, sqlite3_errmsg(db_conn));
      if (results != NULL)
        list_clear(results);
      sqlite3_finalize(stmt);

      return 2;
    }

  if (results != NULL)
    {
      if (results->items > 1)
        results->flags |= LIST_MULTI;
      results->type = LIST_M_UUID_FILE;
    }

  sqlite3_finalize(stmt);

  return (rows == lim->limit) ? 1 : 0;
}
예제 #12
0
파일: db.c 프로젝트: AdUser/xa-tags
/**
 @brief  List tagged files in specified directory
 @param  path     should contain directory name without trailing '/'
 @param  lim      limits of query
 @param  results  list_t to store results (optional)
                  Will be filled with "UUID <> /full/path/to/filename" pairs
 @param  cb       function to call on each found file (optional)
                  Will be called with uuid, filename and tags.
                  I'll assume you know parent dir in place of calling function,
                  so you can reconstruct full paths.
 @returns @c 0 if all data processed, @c 1 if more data expected and @c 2 on error
 */
int
db_file_dirlist(const char *path, query_limits_t *lim, list_t *results,
                int (*cb)(uuid_t, const char *, const char *))
{
  sqlite3_stmt *stmt = NULL;
  char buf[PATH_MAX] = { '\0' };
  uint64_t dirhash = 0;
  size_t len = 0;
  int ret = 0;
  int rows = 0;
  uuid_t uuid = 0;
  char *filename = NULL;
  char *tags = NULL;

  ASSERT(path != NULL && lim != NULL && (results != NULL || cb != NULL), MSG_M_NULLPTR);

  len = strlen(SQL_F_DIRLIST);
  if (sqlite3_prepare_v2(db_conn, SQL_F_DIRLIST, len, &stmt, NULL) != SQLITE_OK)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILPREPARE, sqlite3_errmsg(db_conn));
      return 2;
    }

  if (results != NULL)
    list_clear(results);

  dirhash = crc16(path, strlen(path));
  snprintf(buf, PATH_MAX, "%s%%", path);

  sqlite3_bind_int(stmt, 1, dirhash);
  sqlite3_bind_text(stmt, 2, buf, -1, SQLITE_TRANSIENT);
  sqlite3_bind_int(stmt, 3, lim->limit);
  sqlite3_bind_int64(stmt, 4, lim->offset);

  len = strlen(path);
  while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
    {
      rows++;

      uuid     = (uuid_t) sqlite3_column_int64(stmt, 0);
      filename = (char *) sqlite3_column_text(stmt, 1);
      tags     = (char *) sqlite3_column_text(stmt, 2);

      if (results != NULL)
        {
          len = snprintf_m_uuid_file(buf, PATH_MAX + UUID_CHAR_LEN + 3,
                                     &uuid, filename);
          list_item_add(results, buf, len);
        }

      if (cb != NULL)
        cb(uuid, &filename[len + 1], tags);
    }

  if (ret != SQLITE_DONE)
    {
      msg(msg_warn, COMMON_ERR_FMTN, MSG_D_FAILEXEC, sqlite3_errmsg(db_conn));
      if (results != NULL)
        list_clear(results);
      sqlite3_finalize(stmt);

      return 2;
    }

  if (results != NULL)
    {
      if (results->items > 1)
        results->flags |= LIST_MULTI;
      results->type = LIST_M_UUID_FILE;
    }

  sqlite3_finalize(stmt);

  return (rows == lim->limit) ? 1 : 0;
}