slls_t* split_csvlite_header_line_multi_ifs(char* line, char* ifs, int ifslen, int allow_repeat_ifs) { slls_t* plist = slls_alloc(); if (*line == 0) // empty string splits to empty list return plist; char* p = line; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* start = p; for ( ; *p; p++) { if (streqn(p, ifs, ifslen)) { *p = 0; p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } slls_add_no_free(plist, start); start = p; } } if (allow_repeat_ifs && *start == 0) { ; // OK } else { slls_add_no_free(plist, start); } return plist; }
lrec_t* lrec_parse_stdio_csvlite_data_line_multi_ifs(header_keeper_t* pheader_keeper, char* filename, long long ilno, char* data_line, char* ifs, int ifslen, int allow_repeat_ifs) { lrec_t* prec = lrec_csvlite_alloc(data_line); char* p = data_line; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* key = NULL; char* value = p; sllse_t* pe = pheader_keeper->pkeys->phead; for ( ; *p; ) { if (streqn(p, ifs, ifslen)) { *p = 0; if (pe == NULL) { fprintf(stderr, "%s: Header-data length mismatch in file %s at line %lld.\n", MLR_GLOBALS.argv0, filename, ilno); exit(1); } key = pe->value; pe = pe->pnext; lrec_put(prec, key, value, NO_FREE); p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } value = p; } else { p++; } } if (allow_repeat_ifs && *value == 0) { ; // OK } else if (pe == NULL) { fprintf(stderr, "%s: Header-data length mismatch in file %s at line %lld.\n", MLR_GLOBALS.argv0, filename, ilno); exit(1); } else { key = pe->value; lrec_put(prec, key, value, NO_FREE); if (pe->pnext != NULL) { fprintf(stderr, "%s: Header-data length mismatch in file %s at line %lld.\n", MLR_GLOBALS.argv0, filename, ilno); exit(1); } } return prec; }
lrec_t* lrec_parse_mmap_xtab_multi_ifs(file_reader_mmap_state_t* phandle, char* ifs, char ips, int ifslen, int allow_repeat_ips) { while (phandle->sol < phandle->eof && streqn(phandle->sol, ifs, ifslen)) phandle->sol += ifslen; if (phandle->sol >= phandle->eof) return NULL; lrec_t* prec = lrec_unbacked_alloc(); // Loop over fields, one per line while (TRUE) { char* line = phandle->sol; char* key = line; char* value = ""; char* p; // Construct one field for (p = line; p < phandle->eof && *p; ) { if (streqn(p, ifs, ifslen)) { *p = 0; phandle->sol = p + ifslen; break; } else if (*p == ips) { key = line; *p = 0; p++; if (allow_repeat_ips) { while (*p == ips) p++; } value = p; } else { p++; } } if (p >= phandle->eof) phandle->sol = p+1; lrec_put_no_free(prec, key, value); if (phandle->sol >= phandle->eof || streqn(phandle->sol, ifs, ifslen)) break; } if (prec->field_count == 0) { lrec_free(prec); return NULL; } else { return prec; } }
/* * Extract return value from message returned by lpm_getmsg(). * retval - gets the return value. * msg - the message returned by lpm_getmsg(). * proc - the procedure invoked by lpm_sendmsg()/lpm_que() (i.e., "HandJ"). * Return 1 if return value successfully extracted; else return 0. */ int lpm_retval (int *retval, char *msg, char *proc) { char *cp; if (!msg || !*msg || !streqn (msg, "LPMdone: RETVAL:", 16) || !proc || !*proc || !(cp = strchr (msg + 16, ' ')) || !streqn (cp + 1, proc, strlen (proc))) return 0; *retval = atoi (msg + 16); return 1; }
static slls_t* lrec_reader_mmap_csvlite_get_header_multi_seps(file_reader_mmap_state_t* phandle, lrec_reader_mmap_csvlite_state_t* pstate) { char* irs = pstate->irs; char* ifs = pstate->ifs; int irslen = pstate->irslen; int ifslen = pstate->ifslen; int allow_repeat_ifs = pstate->allow_repeat_ifs; slls_t* pheader_names = slls_alloc(); while ((phandle->eof - phandle->sol) >= irslen && streqn(phandle->sol, irs, irslen)) { phandle->sol += irslen; pstate->ilno++; } char* p = phandle->sol; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* header_name = p; for ( ; p < phandle->eof && *p; ) { if (streqn(p, irs, irslen)) { *p = 0; phandle->sol = p + irslen; pstate->ilno++; break; } else if (streqn(p, ifs, ifslen)) { *p = 0; slls_add_no_free(pheader_names, header_name); p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } header_name = p; } else { p++; } } slls_add_no_free(pheader_names, header_name); return pheader_names; }
static void quote_minimal_output_func(FILE* fp, char* string, char* ors, char* ofs, int orslen, int ofslen) { int output_quotes = FALSE; for (char* p = string; *p; p++) { if (streqn(p, ors, orslen) || streqn(p, ofs, ofslen)) { output_quotes = TRUE; break; } } if (output_quotes) { fputc('"', fp); fputs(string, fp); fputc('"', fp); } else { fputs(string, fp); } }
static const char * get_term_for_tty(const char *tty) { if (streqn(tty, "tty", sizeof("tty") - 1)) { const char *p = tty + sizeof("tty") - 1; if (*p >= '0' && *p <= '9') return "linux"; } return "vt102"; }
// ---------------------------------------------------------------- lrec_t* lrec_parse_stdio_nidx_multi_sep(char* line, char* ifs, int ifslen, int allow_repeat_ifs) { lrec_t* prec = lrec_nidx_alloc(line); int idx = 0; char free_flags = 0; char* p = line; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* key = NULL; char* value = p; for ( ; *p; ) { if (streqn(p, ifs, ifslen)) { *p = 0; idx++; key = make_nidx_key(idx, &free_flags); lrec_put(prec, key, value, free_flags); p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } value = p; } else { p++; } } idx++; if (allow_repeat_ifs && *value == 0) { ; // OK } else { key = make_nidx_key(idx, &free_flags); lrec_put(prec, key, value, free_flags); } return prec; }
lrec_t* lrec_parse_stdio_csvlite_data_line_multi_ifs_implicit_header(header_keeper_t* pheader_keeper, char* filename, long long ilno, char* data_line, char* ifs, int ifslen, int allow_repeat_ifs) { lrec_t* prec = lrec_csvlite_alloc(data_line); char* p = data_line; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* key = NULL; char* value = p; char free_flags; int idx = 0; for ( ; *p; ) { if (streqn(p, ifs, ifslen)) { *p = 0; key = make_nidx_key(++idx, &free_flags); lrec_put(prec, key, value, free_flags); p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } value = p; } else { p++; } } if (allow_repeat_ifs && *value == 0) { ; // OK } else { key = make_nidx_key(++idx, &free_flags); lrec_put(prec, key, value, free_flags); } return prec; }
ATbool ASF_isTagDefault(ASF_ASFTag tag) { if (ASF_isASFTagNotEmpty(tag)) { ASF_ASFTagId tagId = ASF_getASFTagASFTagId(tag); ATbool result; const char *lex = PT_yieldTree((PT_Tree)tagId); result = streqn(lex, DEFAULT_TAG_PREFIX, strlen(DEFAULT_TAG_PREFIX)) || streq(lex, DEFAULT_TAG); return result; } return ATfalse; }
lrec_t* lrec_parse_stdio_xtab_multi_ips(slls_t* pxtab_lines, char* ips, int ipslen, int allow_repeat_ips) { lrec_t* prec = lrec_xtab_alloc(pxtab_lines); for (sllse_t* pe = pxtab_lines->phead; pe != NULL; pe = pe->pnext) { char* line = pe->value; char* p = line; char* key = p; while (*p != 0 && !streqn(p, ips, ipslen)) p++; // Advance by only 1 in case of subsequent match if (*p == 0) { lrec_put(prec, key, "", NO_FREE); } else { while (*p != 0 && !streqn(p, ips, ipslen)) { *p = 0; p += ipslen; } lrec_put(prec, key, p, NO_FREE); } } return prec; }
static void pipe_data_received (DonnaTask *task, DonnaPipe pipe, gsize len, gchar *str, struct data *data) { gchar *s; if (pipe != DONNA_PIPE_ERROR) return; if (!data->str) data->str = g_string_new (NULL); g_string_append_len (data->str, str, (gssize) len); if (data->in_line) { if (!data->in_msg) { s = strchr (data->str->str, '\n'); if (s) { g_string_erase (data->str, 0, s - data->str->str); data->in_line = FALSE; } } } if (!data->in_line && data->str->len >= LEN_PREFIX) { data->in_line = TRUE; data->in_msg = streqn (data->str->str, data->prefix, LEN_PREFIX); } if (data->in_msg) { if (data->is_rm) s = data->str->str; else if (!get_filename (data->str->str, data->openq, data->closeq, NULL, &s)) return; s = strchr (s, '?'); if (s) data->has_question = TRUE; } }
static int parse_cmdline_pin(void) { char **argv = sol_argv(); int argc = sol_argc(); int i; for (i = 1; i < argc; i++) { if (streqn(argv[i], "led-pin=", sizeof("led-pin=") - 1)) { const char *value = argv[i] + sizeof("led-pin=") - 1; int pin = -1; if (sscanf(value, "%d", &pin) == 1) { if (pin > -1) return pin; } } } return -1; }
static void test_coap_token_simple(void) { uint8_t token[] = { 't', 'o', 'k', 'e', 'n' }; uint8_t token_length; uint8_t *token_ptr; struct sol_coap_packet *pkt; pkt = sol_coap_packet_new(NULL); ASSERT(pkt); ASSERT(!sol_coap_header_set_token(pkt, token, sizeof(token))); token_ptr = sol_coap_header_get_token(pkt, &token_length); ASSERT(token_ptr); ASSERT_INT_EQ(token_length, sizeof(token)); ASSERT(streqn((char *)token_ptr, (char *)token, sizeof(token))); ASSERT(!coap_packet_parse(pkt)); sol_coap_packet_unref(pkt); }
int getCommands() { printf("Welcome to the Keyboard Layout Optimizer. If you have questions or comments, contact Michael Dickens by email ([email protected]) or leave a comment at http://mathematicalmulticore.wordpress.com/category/keyboards/.\n"); printf("Type \"help\" for a listing of commands.\n\n"); int length = 5000; char cmd[length]; do { printf(">>> "); fgets(cmd, length, stdin); cmd[strlen(cmd)-1] = '\0'; // Remove the newline. if (streq(cmd, "help")) { printf("algorithm: Run the keyboard optimization algorithm.\n"); printf("best swap <filename>: For the first layout in <filename>, print the single swap that would improve the layout the most.\n"); printf("compare <filename>: Print information about the keyboards in <filename>. The keyboards must be in the proper format.\n"); printf("damaging <filename>: Find the most damaging digraphs for the keyboard layouts in <filename>.\n"); printf("game: Play a keyboard layout game.\n"); printf("get <variable>: Get the value of the specified variable.\n"); printf("improve <filename>: Try to improve the first keyboard in <filename>. The keyboard must be in the proper format.\n"); printf("make typing data: Use the files in freq_types to customize character and digraph frequency.\n"); printf("set <variable> <value>: Set the specified variable to the given value.\n"); printf("setksize <fk_setting>: Set the keyboard type. Type \"setksize help\" for more information.\n"); printf("test fitness: Test that the fitness functions are working properly.\n"); printf("use <keys>: Use <keys> in the keyboard layout instead of the default.\n"); printf("worst <filename>: Find the worst digraphs for the keyboard layouts in <filename>.\n"); printf("variables: Print all variables that can be modified.\n"); printf("quit: Quit the keyboard optimization program.\n"); printf("\n"); } else if (streq(cmd, "algorithm")) { printf("Running the keyboard optimization algorithm. Press ctrl-C to abort.\n\n"); runCJAlgorithm(kbdFilename); } else if (streqn(cmd, "best swap ", strlen("best swap "))) { char *filename = cmd + strlen("best swap "); FILE *fp = fopen(filename, "r"); Keyboard k; if (layoutFromFile(fp, &k) != -1) { layoutFromFile(fp, &k); bestSwap(&k); } fclose(fp); } else if (streqn(cmd, "compare ", 8)) { compare(cmd + 8); } else if (streqn(cmd, "damaging ", 9)) { char *filename = cmd + 9; worstDigraphsFromFile(filename, TRUE); } else if (streq(cmd, "game")) { game(); } else if (streqn(cmd, "get ", 4)) { getValue(cmd + 4); } else if (streqn(cmd, "improve ", strlen("improve "))) { improveFromFile(cmd + 8); } else if (streq(cmd, "make typing data")) { makeTypingData(); } else if (streqn(cmd, "set ", strlen("set "))) { setValue(cmd + 4); } else if (streqn(cmd, "setksize ", strlen("setksize "))) { size_t str_len = strlen("setksize "); if (streq(cmd + str_len, "no")) { setksize(FK_NO); printf("Keyboard set to non-full. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "standard")) { setksize(FK_STANDARD); printf("Keyboard set to full standard. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "kinesis")) { setksize(FK_KINESIS); printf("Keyboard set to full Kinesis. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "iphone")) { setksize(FK_IPHONE); printf("Keyboard set to iPhone. All user-defined values have been reset.\n\n"); } else if (streq(cmd+6, "bs4822")) { setksize(FK_BS4822); printf("Keyboard set to British Standard BS 4822. All user-defined values have been reset.\n\n"); } else { printf("Undefined input. Valid inputs: \"setksize no\" (do not use full keyboard), \"setksize standard\" (use standard full keyboard), \"setksize kinesis\" (use Kinesis full keyboard), \"setksize bs4822\" (use BS 4822 full keyboard).\n\n"); } } else if (streq(cmd, "test fitness")) { testFitness(); } else if (streqn(cmd, "use ", 4)) { strcpy(keysToInclude, cmd + 4); initTypingData(); printf("Now using keys: %s\n\n", cmd + 4); } else if (streq(cmd, "variables")) { printf("Boolean variables should be set to 0 for false and 1 for true. Variables not specified as booleans are integers.\n"); printf("\t(bool) detailedOutput : provide additional information while running the algorithm\n"); printf("\t(bool) keepZXCV : keep keys Z, X, C, and V in place\n"); printf("\t(bool) keepQWERTY : try to keep keys in their QWERTY positions\n"); printf("\t(bool) keepNumbers : keep numbers in place\n"); printf("\t(bool) keepBrackets : keep brackets symmetrical\n"); printf("\t(bool) keepShiftPairs : shifted/unshifted pairs of special characters stay together\n"); printf("\t(bool) keepTab : keep Tab in place\n"); printf("\t(bool) keepNumbersShifted: numbers do not move between shifted and unshifted\n"); printf("\nThese variables determine the costs for particular key combinations. Higher cost is worse.\n"); printf("\tdistance\n"); printf("\tinRoll\n"); printf("\toutRoll\n"); printf("\tsameHand\n"); printf("\tsameFingerP\n"); printf("\tsameFingerR\n"); printf("\tsameFingerM\n"); printf("\tsameFingerI\n"); printf("\trowChangeUp\n"); printf("\trowChangeDown\n"); printf("\thandWarp\n"); printf("\thandSmooth\n"); printf("\thomeJump\n"); printf("\thomeJumpIndex\n"); printf("\tdoubleJump\n"); printf("\ttoCenter\n"); printf("\ttoOutside\n"); } else if (streqn(cmd, "worst ", 6)) { char *filename = cmd + 6; worstDigraphsFromFile(filename, FALSE); } else if (streq(cmd, "quit")) { printf("Goodbye!\n"); break; } else { printf("Unknown command. Type \"help\" for a listing of commands.\n\n"); } } while (strcmp(cmd, "exit") != 0); return 0; }
void tests_util(void) { U32 u = 0; S32 s = 0; hello(); /* * streq() tests. */ /* Simple equality. */ NX_ASSERT(streq("foo", "foo")); /* Simple inequality. */ NX_ASSERT(!streq("foo", "bar")); NX_ASSERT(!streq("bar", "foo")); /* Inequality towards the end of the string. */ NX_ASSERT(!streq("foo", "fob")); NX_ASSERT(!streq("fob", "foo")); /* Inequality of different length strings. */ NX_ASSERT(!streq("foo", "foobar")); NX_ASSERT(!streq("foobar", "foo")); /* Inequality vs. the empty string. */ NX_ASSERT(!streq("foo", "")); NX_ASSERT(!streq("", "foo")); /* The border case of the empty string. */ NX_ASSERT(streq("", "")); /* * streqn() tests. */ /* Simple equality. */ NX_ASSERT(streqn("foo", "foo", 3)); /* Simple inequality. */ NX_ASSERT(!streqn("foo", "bar", 3)); NX_ASSERT(!streqn("bar", "foo", 3)); /* Inequality towards the end of the string. */ NX_ASSERT(!streqn("foo", "fob", 3)); NX_ASSERT(!streqn("fob", "foo", 3)); /* Inequality of different length strings. */ NX_ASSERT(!streqn("foo", "foobar", 6)); NX_ASSERT(!streqn("foobar", "foo", 6)); /* Inequality vs. the empty string. */ NX_ASSERT(!streqn("foo", "", 3)); NX_ASSERT(!streqn("", "foo", 3)); /* Equality of the empty string, no matter the given length. */ NX_ASSERT(streqn("", "", 42)); /* Equality of unequal strings if length == 0 */ NX_ASSERT(streqn("bleh", "foo", 0)); /* Prefix equality of unequal strings */ NX_ASSERT(streqn("feh", "foo", 1)); /* * atou32() tests. */ NX_ASSERT(atou32("42", &u) && u == 42); NX_ASSERT(atou32("0", &u) && u == 0); NX_ASSERT(atou32("00000000000000", &u) && u == 0); NX_ASSERT(atou32("0042", &u) && u == 42); NX_ASSERT(!atou32("arthur", &u)); /* 4294967295 is 2^32-1, aka U32_MAX */ NX_ASSERT(atou32("4294967295", &u) && u == 4294967295U); NX_ASSERT(!atou32("4294967296", &u)); /* TODO: massive overflows don't get caught because of our naive * checking logic. Need to fix. */ NX_ASSERT(atou32("9999999999", &u)); /* * atos32() tests. */ NX_ASSERT(atos32("42", &s) && s == 42); NX_ASSERT(atos32("-42", &s) && s == -42); NX_ASSERT(atos32("0", &s) && s == 0); NX_ASSERT(atos32("-0", &s) && s == 0); NX_ASSERT(atos32("00000000000000", &s) && s == 0); NX_ASSERT(atos32("0042", &s) && s == 42); NX_ASSERT(atos32("-0042", &s) && s == -42); NX_ASSERT(!atos32("arthur", &s)); /* 2147483647 is 2^32-1, aka S32_MAX */ NX_ASSERT(atos32("2147483647", &s) && s == 2147483647); NX_ASSERT(atos32("-2147483647", &s) && s == -2147483647); NX_ASSERT(!atos32("2147483648", &s)); /* TODO: We should be able to represent -2^31, but our conversion logic * considers it an error. Fix it if one day we actually need -2^31. */ NX_ASSERT(!atos32("-2147483648", &s)); /* TODO: massive overflows and underflows don't get caught because * of our naive checking logic. Need to fix. */ NX_ASSERT(atos32("9999999999", &s)); NX_ASSERT(atos32("-9999999999", &s)); goodbye(); }
SOL_API struct sol_message_digest * sol_message_digest_new(const struct sol_message_digest_config *config) { int (*init_fn)(struct sol_message_digest *, const EVP_MD *, const struct sol_str_slice); struct sol_message_digest_common_new_params params; const EVP_MD *md; struct sol_message_digest *handle; int errno_bkp; errno = EINVAL; SOL_NULL_CHECK(config, NULL); SOL_NULL_CHECK(config->on_digest_ready, NULL); SOL_NULL_CHECK(config->algorithm, NULL); #ifndef SOL_NO_API_VERSION if (config->api_version != SOL_MESSAGE_DIGEST_CONFIG_API_VERSION) { SOL_WRN("sol_message_digest_config->api_version=%" PRIu16 ", " "expected version is %" PRIu16 ".", config->api_version, SOL_MESSAGE_DIGEST_CONFIG_API_VERSION); return NULL; } #endif if (!did_openssl_load_digests) { OpenSSL_add_all_digests(); did_openssl_load_digests = true; } params.config = config; params.ops = NULL; md = EVP_get_digestbyname(config->algorithm); if (md) { params.context_handle = EVP_MD_CTX_new(); params.context_free = (void (*)(void *))EVP_MD_CTX_free; init_fn = _sol_message_digest_evp_init; params.ops = &_sol_message_digest_evp_ops; SOL_DBG("using evp, md=%p, algorithm=\"%s\"", md, config->algorithm); } else if (streqn(config->algorithm, "hmac(", strlen("hmac("))) { const char *p = config->algorithm + strlen("hmac("); size_t len = strlen(p); params.context_handle = HMAC_CTX_new(); params.context_free = (void (*)(void *))HMAC_CTX_free; if (len > 1 && p[len - 1] == ')') { char *mdname = strndupa(p, len - 1); md = EVP_get_digestbyname(mdname); if (!md) { SOL_WRN("failed to get digest algorithm \"%s\" for \"%s\".", mdname, config->algorithm); return NULL; } init_fn = _sol_message_digest_hmac_init; params.ops = &_sol_message_digest_hmac_ops; SOL_DBG("using hmac, md=%p, algorithm=\"%s\"", md, mdname); } } if (!params.ops) { SOL_WRN("failed to get digest algorithm \"%s\".", config->algorithm); return NULL; } params.digest_size = EVP_MD_size(md); handle = sol_message_digest_common_new(params); SOL_NULL_CHECK(handle, NULL); errno = init_fn(handle, md, config->key); if (errno) goto error; return handle; error: errno_bkp = errno; sol_message_digest_del(handle); errno = errno_bkp; return NULL; }
static lrec_t* lrec_reader_mmap_csvlite_get_record_multi_seps(file_reader_mmap_state_t* phandle, lrec_reader_mmap_csvlite_state_t* pstate, header_keeper_t* pheader_keeper, int* pend_of_stanza) { if (phandle->sol >= phandle->eof) return NULL; char* irs = pstate->irs; char* ifs = pstate->ifs; int irslen = pstate->irslen; int ifslen = pstate->ifslen; int allow_repeat_ifs = pstate->allow_repeat_ifs; lrec_t* prec = lrec_unbacked_alloc(); char* line = phandle->sol; sllse_t* pe = pheader_keeper->pkeys->phead; char* p = line; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } char* key = NULL; char* value = p; for ( ; p < phandle->eof && *p; ) { if (streqn(p, irs, irslen)) { if (p == line) { *pend_of_stanza = TRUE; return NULL; } *p = 0; phandle->sol = p + irslen; break; } else if (streqn(p, ifs, ifslen)) { if (pe == NULL) { // xxx to do: get file-name/line-number context in here. // xxx to do: print what the lengths are. fprintf(stderr, "Header-data length mismatch!\n"); exit(1); } *p = 0; key = pe->value; lrec_put_no_free(prec, key, value); p += ifslen; if (allow_repeat_ifs) { while (streqn(p, ifs, ifslen)) p += ifslen; } value = p; pe = pe->pnext; } else { p++; } } if (p >= phandle->eof) phandle->sol = p+1; if (pe == NULL) { fprintf(stderr, "Header-data length mismatch!\n"); exit(1); } if (allow_repeat_ifs && *value == 0) { ; // OK } else { key = pe->value; lrec_put_no_free(prec, key, value); if (pe->pnext != NULL) { fprintf(stderr, "Header-data length mismatch!\n"); exit(1); } } return prec; }
/* Parse a complete file from the stream in 's'. If a parse error happens, do not return; instead exit via parseError(). If an out-of-memory condition happens, do not return; instead exit via mallocError(). */ static CacheProfFile* parse_CacheProfFile ( SOURCE* s ) { #define M_TMP_DESCLINES 10 Int i; Bool b; char* tmp_desclines[M_TMP_DESCLINES]; char* p; int n_tmp_desclines = 0; CacheProfFile* cpf; Counts* summaryRead; char* curr_fn_init = "???"; char* curr_fl_init = "???"; char* curr_fn = curr_fn_init; char* curr_fl = curr_fl_init; cpf = new_CacheProfFile( NULL, NULL, NULL, 0, NULL, NULL, NULL ); if (cpf == NULL) mallocFail(s, "parse_CacheProfFile(1)"); // Parse "desc:" lines while (1) { b = readline(s); if (!b) break; if (!streqn(line, "desc: ", 6)) break; if (n_tmp_desclines >= M_TMP_DESCLINES) barf(s, "M_TMP_DESCLINES too low; increase and recompile"); tmp_desclines[n_tmp_desclines++] = strdup(line); } if (n_tmp_desclines == 0) parseError(s, "parse_CacheProfFile: no DESC lines present"); cpf->desc_lines = malloc( (1+n_tmp_desclines) * sizeof(char*) ); if (cpf->desc_lines == NULL) mallocFail(s, "parse_CacheProfFile(2)"); cpf->desc_lines[n_tmp_desclines] = NULL; for (i = 0; i < n_tmp_desclines; i++) cpf->desc_lines[i] = tmp_desclines[i]; // Parse "cmd:" line if (!streqn(line, "cmd: ", 5)) parseError(s, "parse_CacheProfFile: no CMD line present"); cpf->cmd_line = strdup(line); if (cpf->cmd_line == NULL) mallocFail(s, "parse_CacheProfFile(3)"); // Parse "events:" line and figure out how many events there are b = readline(s); if (!b) parseError(s, "parse_CacheProfFile: eof before EVENTS line"); if (!streqn(line, "events: ", 8)) parseError(s, "parse_CacheProfFile: no EVENTS line present"); // figure out how many events there are by counting the number // of space-alphanum transitions in the events_line cpf->events_line = strdup(line); if (cpf->events_line == NULL) mallocFail(s, "parse_CacheProfFile(3)"); cpf->n_events = 0; assert(cpf->events_line[6] == ':'); for (p = &cpf->events_line[6]; *p; p++) { if (p[0] == ' ' && isalpha(p[1])) cpf->n_events++; } // create the running cross-check summary cpf->summary = new_Counts_Zeroed( cpf->n_events ); if (cpf->summary == NULL) mallocFail(s, "parse_CacheProfFile(4)"); // create the outer map (file+fn name --> inner map) cpf->outerMap = newFM ( malloc, free, cmp_FileFn ); if (cpf->outerMap == NULL) mallocFail(s, "parse_CacheProfFile(5)"); // process count lines while (1) { b = readline(s); if (!b) parseError(s, "parse_CacheProfFile: eof before SUMMARY line"); if (isdigit(line[0])) { handle_counts(s, cpf, curr_fl, curr_fn, line); continue; } else if (streqn(line, "fn=", 3)) { if (curr_fn != curr_fn_init) free(curr_fn); curr_fn = strdup(line+3); continue; } else if (streqn(line, "fl=", 3)) { if (curr_fl != curr_fl_init) free(curr_fl); curr_fl = strdup(line+3); continue; } else if (streqn(line, "summary: ", 9)) { break; } else parseError(s, "parse_CacheProfFile: unexpected line in main data"); } // finally, the "summary:" line if (!streqn(line, "summary: ", 9)) parseError(s, "parse_CacheProfFile: missing SUMMARY line"); cpf->summary_line = strdup(line); if (cpf->summary_line == NULL) mallocFail(s, "parse_CacheProfFile(6)"); // there should be nothing more b = readline(s); if (b) parseError(s, "parse_CacheProfFile: " "extraneous content after SUMMARY line"); // check the summary counts are as expected summaryRead = splitUpCountsLine( s, NULL, &cpf->summary_line[8] ); if (summaryRead == NULL) mallocFail(s, "parse_CacheProfFile(7)"); if (summaryRead->n_counts != cpf->n_events) parseError(s, "parse_CacheProfFile: wrong # counts in SUMMARY line"); for (i = 0; i < summaryRead->n_counts; i++) { if (summaryRead->counts[i] != cpf->summary->counts[i]) { parseError(s, "parse_CacheProfFile: " "computed vs stated SUMMARY counts mismatch"); } } free(summaryRead->counts); sdel_Counts(summaryRead); // since the summary counts are OK, free up the summary_line text // which contains the same info. if (cpf->summary_line) { free(cpf->summary_line); cpf->summary_line = NULL; } if (curr_fn != curr_fn_init) free(curr_fn); if (curr_fl != curr_fl_init) free(curr_fl); // All looks OK return cpf; #undef N_TMP_DESCLINES }
static lrec_t* lrec_parse_mmap_xtab_multi_ifs_multi_ips(file_reader_mmap_state_t* phandle, lrec_reader_mmap_xtab_state_t* pstate) { char* ips = pstate->ips; int ipslen = pstate->ipslen; char* ifs = pstate->ifs; int ifslen = pstate->ifslen; // Skip blank lines while (phandle->eof - phandle->sol >= ifslen && streqn(phandle->sol, ifs, ifslen)) { phandle->sol += ifslen; } if (phandle->sol >= phandle->eof) return NULL; lrec_t* prec = lrec_unbacked_alloc(); // Loop over fields, one per line while (TRUE) { if (phandle->sol >= phandle->eof) break; char* line = phandle->sol; char* key = line; char* value = ""; char* p; // Construct one field int saw_eol = FALSE; for (p = line; p < phandle->eof && *p; ) { if (streqn(p, ifs, ifslen)) { *p = 0; phandle->sol = p + ifslen; saw_eol = TRUE; break; } else if (streqn(p, ips, ipslen)) { key = line; *p = 0; p += ipslen; if (pstate->allow_repeat_ips) { while (streqn(p, ips, ipslen)) p += ipslen; } value = p; } else { p++; } } if (p >= phandle->eof) phandle->sol = p+1; if (saw_eol) { // Easy and simple case: we read until end of line. We zero-poked the irs to a null character to terminate // the C string so it's OK to retain a pointer to that. lrec_put(prec, key, value, NO_FREE); } else { // Messier case: we read to end of file without seeing end of line. We can't always zero-poke a null // character to terminate the C string: if the file size is not a multiple of the OS page size it'll work // (it's our copy-on-write memory). But if the file size is a multiple of the page size, then zero-poking at // EOF is one byte past the page and that will segv us. char* copy = mlr_alloc_string_from_char_range(value, phandle->eof - value); lrec_put(prec, key, copy, FREE_ENTRY_VALUE); } if (phandle->sol >= phandle->eof || streqn(phandle->sol, ifs, ifslen)) break; } if (prec->field_count == 0) { lrec_free(prec); return NULL; } else { return prec; } }
SOL_API double sol_util_strtod_n(const char *nptr, char **endptr, ssize_t len, bool use_locale) { char *tmpbuf, *tmpbuf_endptr; double value; #if defined(HAVE_NEWLOCALE) && defined(HAVE_STRTOD_L) if (!use_locale) { if (!init_c_locale()) { /* not great, but a best effort to convert something */ use_locale = false; SOL_WRN("could not create locale 'C', use current locale."); } } #endif if (len < 0) len = (ssize_t)strlen(nptr); if (SOL_UNLIKELY(len > (DBL_MANT_DIG - DBL_MIN_EXP + 3))) { errno = EINVAL; return FP_NAN; } /* NOTE: Using a copy to ensure trailing \0 and strtod() so we * properly parse numbers with large precision. * * Since parsing it is complex (ie: * http://www.netlib.org/fp/dtoa.c), we take the short path to * call libc. */ tmpbuf = strndupa(nptr, len); errno = 0; #ifdef HAVE_NEWLOCALE if (!use_locale) { #ifdef HAVE_STRTOD_L value = strtod_l(tmpbuf, &tmpbuf_endptr, c_locale); #else /* fallback to query locale's decimal point and if it's * different than '.' we replace JSON's '.' with locale's * decimal point if the given number contains a '.'. * * We also replace any existing locale decimal_point with '.' * so it will return correct endptr. * * Extra care since decimal point may be multi-byte. */ struct lconv *lc = localeconv(); if (lc && lc->decimal_point && !streq(lc->decimal_point, ".")) { if (strchr(tmpbuf, '.') || strstr(tmpbuf, lc->decimal_point)) { int dplen = strlen(lc->decimal_point); const char *src, *src_end = tmpbuf + len; char *dst; if (dplen == 1) { for (src = tmpbuf, dst = tmpbuf; src < src_end; src++, dst++) { if (*src == '.') *dst = *lc->decimal_point; else if (*src == *lc->decimal_point) *dst = '.'; } } else { char *transl; unsigned count = 0; for (src = tmpbuf; src < src_end; src++) { if (*src == '.') count++; } transl = alloca(len + (count * dplen) + 1); for (src = tmpbuf, dst = transl; src < src_end;) { if (*src == '.') { memcpy(dst, lc->decimal_point, dplen); dst += dplen; src++; } else if ((src_end - src) >= dplen && streqn(src, lc->decimal_point, dplen)) { *dst = '.'; dst++; src += dplen; } else { *dst = *src; dst++; src++; } } *dst = '\0'; tmpbuf = transl; } } } value = strtod(tmpbuf, &tmpbuf_endptr); #endif } else #endif { value = strtod(tmpbuf, &tmpbuf_endptr); } if (endptr) *endptr = (char *)nptr + (tmpbuf_endptr - tmpbuf); return value; }
int getCommands() { printf("Welcome to the Keyboard Layout Optimizer. If you have questions or comments, contact Michael Dickens by email ([email protected]) or leave a comment at http://mathematicalmulticore.wordpress.com/category/keyboards/.\n"); printf("Type \"help\" for a listing of commands.\n\n"); int length = 5000; char cmd[length]; do { printf(">>> "); fgets(cmd, length, stdin); cmd[strlen(cmd)-1] = '\0'; // Remove the newline. if (streq(cmd, "help")) { printf("algorithm: Run the keyboard optimization algorithm.\n"); printf("best swap <filename>: For the first layout in <filename>, print the single swap that would improve the layout the most.\n"); printf("compare <filename>: Print information about the keyboards in <filename>. The keyboards must be in the proper format.\n"); printf("damaging <filename>: Find the most damaging digraphs for the keyboard layouts in <filename>.\n"); printf("game: Play a keyboard layout game.\n"); printf("get <variable>: Get the value of the specified variable.\n"); printf("improve <filename>: Try to improve the first keyboard in <filename>. The keyboard must be in the proper format.\n"); printf("make typing data: Use the files in freq_types to customize character and digraph frequency.\n"); printf("run: See 'algorithm'.\n"); printf("set <variable> <value>: Set the specified variable to the given value.\n"); printf("setksize <K_setting>: Set the keyboard type. Type \"setksize help\" for more information.\n"); printf("test fitness: Test that the fitness functions are working properly.\n"); printf("use <keys>: Use <keys> in the keyboard layout instead of the default.\n"); printf("worst <filename>: Find the worst digraphs for the keyboard layouts in <filename>.\n"); printf("variables: Print all variables that can be modified.\n"); printf("quit: Quit the keyboard optimization program.\n"); printf("\n"); } else if (streq(cmd, "algorithm") || streq(cmd, "run")) { printf("Running the keyboard optimization algorithm. Press ctrl-C to quit.\n\n"); runAlgorithm(); } else if (streqn(cmd, "best swap ", strlen("best swap "))) { const char *const filename = cmd + strlen("best swap "); FILE *file = fopen(filename, "r"); CHECK_FILE_FOR_NULL(file, filename); Keyboard k; if (layoutFromFile(file, &k) != -1) { bestSwap(&k); } fclose(file); } else if (streqn(cmd, "compare ", 8)) { compare(cmd + 8); } else if (streqn(cmd, "damaging ", 9)) { const char *const filename = cmd + 9; worstDigraphsFromFile(filename, TRUE); } else if (streq(cmd, "game")) { game(); } else if (streqn(cmd, "get ", 4)) { getValue(cmd + 4); } else if (streqn(cmd, "improve ", strlen("improve "))) { improveFromFile(cmd + 8); } else if (streq(cmd, "make typing data")) { makeTypingData(); } else if (streqn(cmd, "set ", strlen("set "))) { setValue(cmd + 4); } else if (streqn(cmd, "setksize ", strlen("setksize "))) { size_t str_len = strlen("setksize "); if (streq(cmd + str_len, "no")) { setksize(K_NO); printf("Keyboard set to non-full. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "standard")) { setksize(K_STANDARD); printf("Keyboard set to full standard. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "kinesis")) { setksize(K_KINESIS); printf("Keyboard set to full Kinesis. All user-defined values have been reset.\n\n"); } else if (streq(cmd + str_len, "iphone")) { setksize(K_IPHONE); printf("Keyboard set to iPhone. All user-defined values have been reset.\n\n"); } else { printf("Undefined input. Valid inputs: \"setksize no\" (do not use full keyboard), \"setksize standard\" (use standard full keyboard), \"setksize kinesis\" (use Kinesis full keyboard).\n\n"); } } else if (streq(cmd, "test fitness")) { testFitness(); } else if (streqn(cmd, "use ", 4)) { strcpy(keysToInclude, cmd + 4); initTypingData(); printf("Now using keys: %s\n\n", cmd + 4); } else if (streq(cmd, "variables")) { printf("Boolean variables should be set to 0 for false and 1 for true. Variables not specified as booleans are integers.\n"); int i; for (i = 0; i < variablesLength; ++i) { printf("\t%s", variables[i].name); if (variables[i].description) printf(": %s", variables[i].description); printf("\n"); } printf("\n"); } else if (streqn(cmd, "worst ", 6)) { const char *const filename = cmd + 6; worstDigraphsFromFile(filename, FALSE); } else if (streq(cmd, "quit")) { printf("Goodbye!\n"); break; } else { printf("Unknown command. Type \"help\" for a listing of commands.\n\n"); } } while (strcmp(cmd, "exit") != 0); return 0; }
// ---------------------------------------------------------------- static char * test_streqn() { char* x; char* y; x = ""; y = ""; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = ""; y = "1"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = ""; y = "12"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = ""; y = "123"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = ""; y = ""; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "a"; y = ""; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "ab"; y = ""; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "abc"; y = ""; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "a"; y = "a"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "a"; y = "aa"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "a"; y = "ab"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "a"; y = "abd"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "ab"; y = "a"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "ab"; y = "ab"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "ab"; y = "abd"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "abc"; y = "a"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "abc"; y = "ab"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "abc"; y = "abc"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); x = "abc"; y = "abd"; mu_assert_lf(streqn(x, y, 2) == !strncmp(x, y, 2)); return 0; }
static gboolean ct_text_get_context_item_info (DonnaColumnType *ct, gpointer _data, const gchar *item, const gchar *extra, DonnaContextReference reference, DonnaNode *node_ref, get_sel_fn get_sel, gpointer get_sel_data, DonnaContextInfo *info, GError **error) { struct tv_col_data *data = _data; const gchar *value = NULL; const gchar *ask_title = NULL; const gchar *ask_current = NULL; const gchar *save_location = NULL; save_location = DONNA_COLUMN_TYPE_GET_INTERFACE (ct)-> helper_get_save_location (ct, &extra, FALSE, error); if (!save_location) return FALSE; if (streq (item, "property")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->name = g_strconcat ("Node Property: ", data->property, NULL); info->free_name = TRUE; ask_title = "Enter the name of the property"; ask_current = data->property; } else if (streqn (item, "align", 5)) { info->is_visible = info->is_sensitive = TRUE; if (item[5] == '\0') { info->name = "Alignment"; info->submenus = 1; return TRUE; } else if (item[5] == '.') { if (!_donna_context_set_item_from_extra (info, donna_app_peek_config (((DonnaColumnTypeText *) ct)->priv->app), "align", DONNA_CONFIG_EXTRA_TYPE_LIST_INT, TRUE, "align", item + 6, data->align, save_location, error)) { g_prefix_error (error, "ColumnType '%s': Failed to get item '%s': ", "text", item); return FALSE; } return TRUE; } else { g_set_error (error, DONNA_CONTEXT_MENU_ERROR, DONNA_CONTEXT_MENU_ERROR_UNKNOWN_ITEM, "ColumnType '%s': No such item: '%s'", "text", item); return FALSE; } } else if (streq (item, "property_tooltip")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->name = g_strconcat ("Node Property (tooltip): ", (data->property_tooltip) ? data->property_tooltip : ":property", NULL); info->free_name = TRUE; info->desc = "Name of the property shown in tooltip. Use :property to use the same one."; ask_title = "Enter the name of the property to be shown on tooltip"; ask_current = (data->property_tooltip) ? data->property_tooltip : ":property"; } else if (streq (item, "natural_order")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->icon_special = DONNA_CONTEXT_ICON_IS_CHECK; info->is_active = (data->options & DONNA_SORT_NATURAL_ORDER) ? TRUE : FALSE; info->name = "Natural Order"; value = (info->is_active) ? "0" : "1"; } else if (streq (item, "dot_first")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->icon_special = DONNA_CONTEXT_ICON_IS_CHECK; info->is_active = (data->options & DONNA_SORT_DOT_FIRST) ? TRUE : FALSE; info->name = "Show \"dot files\" first"; value = (info->is_active) ? "0" : "1"; } else if (streq (item, "case_sensitive")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->icon_special = DONNA_CONTEXT_ICON_IS_CHECK; info->is_active = (data->options & DONNA_SORT_CASE_INSENSITIVE) ? FALSE: TRUE; info->name = "Case Sensitive"; value = (info->is_active) ? "0" : "1"; } else if (streq (item, "dot_mixed")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->icon_special = DONNA_CONTEXT_ICON_IS_CHECK; info->is_active = (data->options & DONNA_SORT_DOT_MIXED) ? TRUE : FALSE; info->name = "Sort \"dot files\" amongst others"; value = (info->is_active) ? "0" : "1"; } else if (streq (item, "ignore_spunct")) { info->is_visible = TRUE; info->is_sensitive = TRUE; info->icon_special = DONNA_CONTEXT_ICON_IS_CHECK; info->is_active = (data->options & DONNA_SORT_IGNORE_SPUNCT) ? TRUE : FALSE; info->name = "Ignore leading spunctuation characters"; value = (info->is_active) ? "0" : "1"; } else { g_set_error (error, DONNA_CONTEXT_MENU_ERROR, DONNA_CONTEXT_MENU_ERROR_UNKNOWN_ITEM, "ColumnType 'text': Unknown item '%s'", item); return FALSE; } info->trigger = DONNA_COLUMN_TYPE_GET_INTERFACE (ct)-> helper_get_set_option_trigger (item, value, FALSE, ask_title, NULL, ask_current, save_location); info->free_trigger = TRUE; return TRUE; }
// ---------------------------------------------------------------- static lrec_t* lrec_reader_stdio_csv_process(void* pvstate, void* pvhandle, context_t* pctx) { lrec_reader_stdio_csv_state_t* pstate = pvstate; // Ingest the next header line, if expected if (pstate->expect_header_line_next) { while (TRUE) { if (!lrec_reader_stdio_csv_get_fields(pstate, pstate->pfields, pctx, TRUE)) return NULL; pstate->ilno++; // We check for comments here rather than within the parser since it's important // for users to be able to comment out lines containing double-quoted newlines. if (pstate->comment_string != NULL && pstate->pfields->phead != NULL) { if (streqn(pstate->pfields->phead->value, pstate->comment_string, pstate->comment_string_length)) { if (pstate->comment_handling == PASS_COMMENTS) { int i = 0; for ( rsllse_t* pe = pstate->pfields->phead; i < pstate->pfields->length && pe != NULL; pe = pe->pnext, i++) { if (i > 0) fputs(pstate->ifs, stdout); fputs(pe->value, stdout); } if (pstate->do_auto_line_term) { fputs(pctx->auto_line_term, stdout); } else { fputs(pstate->irs, stdout); } } rslls_reset(pstate->pfields); continue; } } slls_t* pheader_fields = slls_alloc(); int i = 0; for (rsllse_t* pe = pstate->pfields->phead; i < pstate->pfields->length && pe != NULL; pe = pe->pnext) { if (*pe->value == 0) { fprintf(stderr, "%s: unacceptable empty CSV key at file \"%s\" line %lld.\n", MLR_GLOBALS.bargv0, pctx->filename, pstate->ilno); exit(1); } // Transfer pointer-free responsibility from the rslls to the // header fields in the header keeper slls_append(pheader_fields, pe->value, pe->free_flag); pe->free_flag = 0; } rslls_reset(pstate->pfields); pstate->pheader_keeper = lhmslv_get(pstate->pheader_keepers, pheader_fields); if (pstate->pheader_keeper == NULL) { pstate->pheader_keeper = header_keeper_alloc(NULL, pheader_fields); lhmslv_put(pstate->pheader_keepers, pheader_fields, pstate->pheader_keeper, NO_FREE); // freed by header-keeper } else { // Re-use the header-keeper in the header cache slls_free(pheader_fields); } pstate->expect_header_line_next = FALSE; break; } } // Ingest the next data line, if expected while (TRUE) { int rc = lrec_reader_stdio_csv_get_fields(pstate, pstate->pfields, pctx, FALSE); pstate->ilno++; if (rc == FALSE) // EOF return NULL; // We check for comments here rather than within the parser since it's important // for users to be able to comment out lines containing double-quoted newlines. if (pstate->comment_string != NULL && pstate->pfields->phead != NULL) { if (streqn(pstate->pfields->phead->value, pstate->comment_string, pstate->comment_string_length)) { if (pstate->comment_handling == PASS_COMMENTS) { int i = 0; for ( rsllse_t* pe = pstate->pfields->phead; i < pstate->pfields->length && pe != NULL; pe = pe->pnext, i++) { if (i > 0) fputs(pstate->ifs, stdout); fputs(pe->value, stdout); } if (pstate->do_auto_line_term) { fputs(pctx->auto_line_term, stdout); } else { fputs(pstate->irs, stdout); } } rslls_reset(pstate->pfields); continue; } } lrec_t* prec = pstate->use_implicit_header ? paste_indices_and_data(pstate, pstate->pfields, pctx) : paste_header_and_data(pstate, pstate->pfields, pctx); rslls_reset(pstate->pfields); return prec; } }
/* * Compile the typing data from each of the given files into a single file. * * outfileName: The file to which the new typing data will be written. * filenames: The names of each file to be read. * multipliers: The multipliers corresponding with the filenames. * length: Length of filenames and multipliers. * unit: The unit size of the strings to be read (characters=1, digraphs=2, etc). * max: The maximum number of strings that can be put into the file. * * Return Codes * 1: Null file. */ int compileTypingData(char *outfileName, char *filenames[], int multipliers[], int length, int unit, int max) { size_t size = 5000; char **keys = malloc(sizeof(char *) * size); int *values = malloc(sizeof(int) * size); /* Number of elements in keys and values. */ int datalen = 0; int linelen = 100; char line[linelen]; FILE *outfile = fopen(outfileName, "w"); if (outfile == NULL) { fprintf(stderr, "Error: null file %s.\n", outfileName); return 1; } int i, k; for (i = 0; i < length; ++i) { printf("file %s, multiplier %d\n", filenames[i], multipliers[i]); if (multipliers[i] == 0) continue; FILE *file = fopen(filenames[i], "r"); if (file == NULL) { fprintf(stderr, "Error: null file %s.\n", filenames[i]); fclose(outfile); return 1; } while (fgets(line, linelen-1, file)) { line[linelen-1] = '\0'; if (datalen >= size) { size *= 2; keys = realloc(keys, sizeof(char) * size); values = realloc(values, sizeof(int) * size); } /* If the n-graph already exists, add to its value. */ int found = FALSE; for (k = 0; k < datalen; ++k) { if (streqn(keys[k], line, unit)) { found = TRUE; values[k] += atoi(line + unit + 1) * multipliers[i]; } } /* If the n-graph does not already exist, add it. */ if (found == FALSE) { keys[datalen] = malloc(sizeof(char) * (unit + 1)); strncpy(keys[datalen], line, unit); keys[datalen][unit] = '\0'; values[k] = atoi(line + unit + 1) * multipliers[i]; ++datalen; } } fclose(file); } sortTypingData(keys, values, 0, datalen-1); for (i = 0; i < datalen && i < max; ++i) { strncpy(line, keys[i], unit); sprintf(line + unit, " %d\n", values[i]); fputs(line, outfile); free(keys[i]); } fclose(outfile); free(keys); free(values); return 0; }
char* mlr_unbackslash(char* input) { char* output = strdup(input); char* pi = input; char* po = output; int code = 0; while (*pi) { // https://en.wikipedia.org/wiki/Escape_sequences_in_C if (streqn(pi, "\\a", 2)) { pi += 2; *(po++) = '\a'; } else if (streqn(pi, "\\b", 2)) { pi += 2; *(po++) = '\b'; } else if (streqn(pi, "\\f", 2)) { pi += 2; *(po++) = '\f'; } else if (streqn(pi, "\\n", 2)) { pi += 2; *(po++) = '\n'; } else if (streqn(pi, "\\r", 2)) { pi += 2; *(po++) = '\r'; } else if (streqn(pi, "\\t", 2)) { pi += 2; *(po++) = '\t'; } else if (streqn(pi, "\\v", 2)) { pi += 2; *(po++) = '\v'; } else if (streqn(pi, "\\\\", 2)) { pi += 2; *(po++) = '\\'; } else if (streqn(pi, "\\'", 2)) { pi += 2; *(po++) = '\''; } else if (streqn(pi, "\\\"", 2)) { pi += 2; *(po++) = '"'; } else if (streqn(pi, "\\?", 2)) { pi += 2; *(po++) = '?'; } else if (is_backslash_octal(pi, &code)) { pi += 4; *(po++) = code; } else if (is_backslash_hex(pi, &code)) { pi += 4; *(po++) = code; } else { *po = *pi; pi++; po++; } } *po = 0; return output; // xxx temp }
/* * Compile the typing data from each of the given files into a single file. * * outfileName: The file to which the new typing data will be written. * filenames: The names of each file to be read. * multipliers: The multipliers corresponding with the filenames. * length: Length of filenames and multipliers. * unit: The unit size of the strings to be read (characters=1, digraphs=2, etc). * max: The maximum number of strings that can be put into the file. * * Return Codes * 1: Null file. * 2: Allocation failure. * * TODO: Refactor this to use monograph and digraph structs instead of two * parallel arrays of keys and values. */ int compileTypingData(char *outfileName, const char *filenames[], int multipliers[], int length, int unit, int max) { size_t size = 5000; /* Number of elements in keys and values. */ int dataLen = 0; const int lineLen = 100; char line[lineLen]; FILE *outfile = fopen(outfileName, "w"); CHECK_FILE_FOR_NULL(outfile, outfileName); if (outfile == NULL) { fprintf(stderr, "Error: null file %s.\n", outfileName); return 1; } struct NGraph *ngraphs = malloc(sizeof(struct NGraph) * size); if (ngraphs == NULL) { fprintf(stderr, "Error: In compileTypingData(), ngraphs is null (malloc failure).\n"); return 2; } memset(ngraphs, 0, sizeof(struct NGraph) * size); int i, k; for (i = 0; i < length; ++i) { printf("file %s, multiplier %d\n", filenames[i], multipliers[i]); if (multipliers[i] == 0) continue; FILE *file = fopen(filenames[i], "r"); if (file == NULL) { fprintf(stderr, "Error: In compileTypingData(), null file %s.\n", filenames[i]); fclose(outfile); free(ngraphs); return 1; } while (fgets(line, lineLen-1, file)) { if (dataLen >= size) { size *= 2; ngraphs = realloc(ngraphs, sizeof(struct NGraph) * size); if (ngraphs == NULL) { fprintf(stderr, "Error: In compileTypingData(), ngraphs is null (realloc failure).\n"); return 2; } } /* If the n-graph already exists, add to its value. */ int found = FALSE; for (k = 0; k < dataLen; ++k) { if (streqn(ngraphs[k].key, line, unit)) { found = TRUE; ngraphs[k].value += atoi(line + unit + 1) * multipliers[i]; } } /* If the n-graph does not already exist, add it. */ if (found == FALSE) { ngraphs[dataLen].key = malloc(sizeof(char) * (unit + 1)); if (ngraphs[dataLen].key == NULL) { /* TODO: free all allocated memory */ fprintf(stderr, "Error: In compileTypingData(), ngraphs[%d].key is null (malloc failure).\n", dataLen); return 2; } strncpy(ngraphs[dataLen].key, line, unit); ngraphs[dataLen].key[unit] = '\0'; ngraphs[k].value = atoi(line + unit + 1) * multipliers[i]; ++dataLen; } } fclose(file); } qsort(ngraphs, dataLen, sizeof(struct NGraph), cmpNGraphsByValue); for (i = 0; i < dataLen && i < max; ++i) { strncpy(line, ngraphs[i].key, unit); sprintf(line + unit, " %lld\n", ngraphs[i].value); fputs(line, outfile); free(ngraphs[i].key); } fclose(outfile); free(ngraphs); return 0; }
static int validate_iso(struct iso_prim_voldesc *prim) { return (prim->vol_desc_type == 1 && streqn(prim->std_identifier, "CD001", 5) && prim->vol_desc_version == 1); }
static lrec_t* lrec_parse_mmap_xtab_single_ifs_multi_ips(file_reader_mmap_state_t* phandle, char ifs, lrec_reader_mmap_xtab_state_t* pstate, context_t* pctx) { if (pstate->do_auto_line_term) { // Skip over otherwise empty LF-only or CRLF-only lines. while (phandle->sol < phandle->eof) { if (*phandle->sol == '\n') { context_set_autodetected_lf(pctx); phandle->sol += 1; } else if (*phandle->sol == '\r') { char* q = phandle->sol + 1; if (q < phandle->eof && *q == '\n') { context_set_autodetected_crlf(pctx); phandle->sol += 2; } else { phandle->sol += 1; } } else { break; } } } else { // Skip over otherwise empty IFS-only lines. while (phandle->sol < phandle->eof && *phandle->sol == ifs) phandle->sol++; } if (phandle->sol >= phandle->eof) return NULL; char* ips = pstate->ips; int ipslen = pstate->ipslen; lrec_t* prec = lrec_unbacked_alloc(); // Loop over fields, one per line while (TRUE) { if (phandle->sol >= phandle->eof) break; char* line = phandle->sol; char* key = line; char* value = ""; char* p; // Construct one field int saw_eol = FALSE; for (p = line; p < phandle->eof && *p; ) { if (*p == ifs) { *p = 0; if (pstate->do_auto_line_term) { if (p > line && p[-1] == '\r') { p[-1] = 0; context_set_autodetected_crlf(pctx); } else { context_set_autodetected_lf(pctx); } } phandle->sol = p+1; saw_eol = TRUE; break; } else if (streqn(p, ips, ipslen)) { key = line; *p = 0; p += ipslen; if (pstate->allow_repeat_ips) { while (streqn(p, ips, ipslen)) p += ipslen; } value = p; } else { p++; } } if (p >= phandle->eof) phandle->sol = p+1; if (saw_eol) { // Easy and simple case: we read until end of line. We zero-poked the irs to a null character to terminate // the C string so it's OK to retain a pointer to that. lrec_put(prec, key, value, NO_FREE); } else { // Messier case: we read to end of file without seeing end of line. We can't always zero-poke a null // character to terminate the C string: if the file size is not a multiple of the OS page size it'll work // (it's our copy-on-write memory). But if the file size is a multiple of the page size, then zero-poking at // EOF is one byte past the page and that will segv us. char* copy = mlr_alloc_string_from_char_range(value, phandle->eof - value); lrec_put(prec, key, copy, FREE_ENTRY_VALUE); } if (phandle->sol >= phandle->eof || *phandle->sol == ifs) break; } if (prec->field_count == 0) { lrec_free(prec); return NULL; } else { return prec; } }