void test_cangjie_get_characters_multiple_queries() { Cangjie *cj; CangjieCharList *l; CangjieCharList *l2; int ret = cangjie_new(&cj, CANGJIE_VERSION_3, CANGJIE_FILTER_BIG5); assert(ret == CANGJIE_OK); assert(cj->version == CANGJIE_VERSION_3); assert(cj->filter_flags == CANGJIE_FILTER_BIG5); ret = cangjie_get_characters(cj, "h*i", &l); assert(ret == CANGJIE_OK); cangjie_char_list_free(l); ret = cangjie_get_characters(cj, "dmlm", &l2); assert(ret == CANGJIE_OK); assert(strcmp(l2->c->chchar, "椏") == 0); assert(strcmp(l2->c->code, "dmlm") == 0); assert(l2->c->frequency == 10253); assert(l2->next == NULL); cangjie_char_list_free(l2); cangjie_free(cj); }
void test_cangjie_new() { Cangjie *cj; int ret = cangjie_new(&cj, CANGJIE_VERSION_3, CANGJIE_FILTER_BIG5); assert(ret == CANGJIE_OK); assert(cj->version == CANGJIE_VERSION_3); assert(cj->filter_flags == CANGJIE_FILTER_BIG5); cangjie_free(cj); }
int cangjie_new(Cangjie **cj, CangjieVersion version, CangjieFilter filter_flags) { char *filter_query; int ret; char *database_path; Cangjie *tmp = calloc(1, sizeof(Cangjie)); if (tmp == NULL) { return CANGJIE_NOMEM; } tmp->version = version; tmp->filter_flags = filter_flags; // Prepare the main Cangjie query tmp->cj_query = calloc(strlen(BASE_QUERY) + MAX_LEN_FILTER_QUERY + 1, sizeof(char)); if (tmp->cj_query == NULL) { cangjie_free(tmp); return CANGJIE_NOMEM; } strcat(tmp->cj_query, BASE_QUERY); ret = cangjie_get_filter_query(tmp, &filter_query); if (ret != CANGJIE_OK) { cangjie_free(tmp); return ret; } strcat(tmp->cj_query, filter_query); free(filter_query); // Prepare the query by short code tmp->shortcode_query = calloc(strlen(BASE_QUERY) + MAX_LEN_CODE_QUERY + 1, sizeof(char)); if (tmp->shortcode_query == NULL) { cangjie_free(tmp); return CANGJIE_NOMEM; } strcat(tmp->shortcode_query, BASE_QUERY); strcat(tmp->shortcode_query, "AND code = '%q';"); // Check the CANGJIE_DB env var (it is useful for local testing) database_path = getenv("CANGJIE_DB"); if (database_path != NULL) { ret = sqlite3_open_v2(database_path, &tmp->db, SQLITE_OPEN_READONLY, NULL); } else { ret = sqlite3_open_v2(CANGJIE_DB, &tmp->db, SQLITE_OPEN_READONLY, NULL); } if (ret == SQLITE_CANTOPEN) { cangjie_free(tmp); return CANGJIE_DBOPEN; } else if (ret != SQLITE_OK) { cangjie_free(tmp); // FIXME: Unhandled error codes return ret; } *cj = tmp; return CANGJIE_OK; }
int main(int argc, char **argv) { char *code; Cangjie *cj; int ret; CangjieCharList *chars; CangjieCharList *iter; CangjieChar *c; // variables to parse options int opt; int option_index; // option flags int opt_filter; CangjieCliMode opt_mode; int opt_cj_version; // helper variable(s) char errmsg[255]; char *code_ptr; char *ptr_radical; // available options static struct option long_options[] = { {"filter", required_argument, 0, 'f'}, {"mode", required_argument, 0, 'm'}, {"cj-version", required_argument, 0, 'C'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}, }; // default options opt_filter = CANGJIE_FILTER_BIG5 | CANGJIE_FILTER_HKSCS; opt_mode = CANGJIE_CLI_MODE_CODE; opt_cj_version = CANGJIE_VERSION_3; // read options while (1) { option_index = 0; opt = getopt_long(argc, argv, "f:m:C:h", long_options, &option_index); if (opt == -1) { break; } switch (opt) { case 'f': opt_filter = 0; if (strstr(optarg, "big5") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_BIG5; } if (strstr(optarg, "hkscs") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_HKSCS; } if (strstr(optarg, "punctuation") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_PUNCTUATION; } if (strstr(optarg, "chinese") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_CHINESE; } if (strstr(optarg, "zhuyin") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_ZHUYIN; } if (strstr(optarg, "kanji") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_KANJI; } if (strstr(optarg, "katakana") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_KATAKANA; } if (strstr(optarg, "hiragana") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_HIRAGANA; } if (strstr(optarg, "symbols") != NULL) { opt_filter = opt_filter | CANGJIE_FILTER_SYMBOLS; } if (opt_filter == 0) { sprintf(errmsg, "Invalid filter option '%s'", optarg); print_error(errmsg); return -1; } break; case 'm': if (strcmp(optarg, "code") == 0) { opt_mode = CANGJIE_CLI_MODE_CODE; } else if (strcmp(optarg, "shortcode") == 0) { opt_mode = CANGJIE_CLI_MODE_SHORTCODE; } else if (strcmp(optarg, "radical") == 0) { opt_mode = CANGJIE_CLI_MODE_RADICAL; } else { sprintf(errmsg, "Invalid query mode '%s'", optarg); print_error(errmsg); return -1; } break; case 'C': if (*optarg == '3') { opt_cj_version = CANGJIE_VERSION_3; } else if (*optarg == '5') { opt_cj_version = CANGJIE_VERSION_5; } else { sprintf(errmsg, "Invalid Cangjie version '%s'", optarg); print_error(errmsg); return -1; } break; case '?': printf("Try 'libcangjie_cli --help' for more information\n"); return -1; break; case 'h': default: usage(argv[0]); return (opt == 'h') ? 0 : -1; } } // check if query provided if (optind == argc) { print_error("missing query code"); return -1; } code = argv[optind]; ret = cangjie_new(&cj, opt_cj_version, opt_filter); if (ret == CANGJIE_DBOPEN) { printf("Could not open the Cangjie database\n"); return ret; } else if (ret != CANGJIE_OK) { printf("Unhandled error while creating the Cangjie object: %d\n", ret); return ret; } if (opt_mode == CANGJIE_CLI_MODE_RADICAL) { code_ptr = code; for (; *code_ptr != '\0'; code_ptr++) { ret = cangjie_get_radical(cj, *code_ptr, &ptr_radical); if (ret == CANGJIE_OK) { printf("code: '%c', radical: '%s'\n", *code_ptr, ptr_radical); } else { printf("Query error (%d)\n", ret); return ret; } } return ret; } else { if (opt_mode == CANGJIE_CLI_MODE_CODE) { ret = cangjie_get_characters(cj, code, &chars); } else if (opt_mode == CANGJIE_CLI_MODE_SHORTCODE) { ret = cangjie_get_characters_by_shortcode(cj, code, &chars); } if (ret == CANGJIE_NOCHARS) { printf("No chars with code '%s'\n", code); cangjie_free(cj); return CANGJIE_NOCHARS; } else if (ret == CANGJIE_INVALID) { printf("Invalid code '%s'\n", code); cangjie_free(cj); return CANGJIE_INVALID; } else if (ret != CANGJIE_OK) { printf("Other error %d with code '%s'\n", ret, code); cangjie_free(cj); return ret; } iter = chars; while (1) { if (iter == NULL) { break; } c = iter->c; printf("Char: '%s', SimpChar: '%s', code: '%s', classic frequency: %d\n", c->chchar, c->simpchar, c->code, c->frequency); iter = iter->next; } cangjie_char_list_free(chars); } cangjie_free(cj); return CANGJIE_OK; }