- Timestamp:
- Dec 28, 2008 2:10:38 AM (16 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/Makefile.am
r2141 r2151 143 143 -DCONFIG_WITH_MINIMAL_STATS \ 144 144 -DCONFIG_WITH_COMMANDS_FUNC \ 145 -DCONFIG_WITH_STRING_FUNCTIONS \ 145 146 -DCONFIG_PRETTY_COMMAND_PRINTING \ 146 147 -DCONFIG_WITH_PRINT_STATS_SWITCH \ -
trunk/src/kmk/Makefile.kmk
r2145 r2151 168 168 CONFIG_WITH_MINIMAL_STATS \ 169 169 CONFIG_WITH_COMMANDS_FUNC \ 170 CONFIG_WITH_PRINTF \ 171 CONFIG_WITH_STRING_FUNCTIONS \ 170 172 CONFIG_PRETTY_COMMAND_PRINTING \ 171 173 CONFIG_WITH_PRINT_STATS_SWITCH \ -
trunk/src/kmk/function.c
r2149 r2151 50 50 typedef big_int math_int; 51 51 static char *math_int_to_variable_buffer (char *, math_int); 52 static math_int math_int_from_string (const char *str); 52 53 #endif 53 54 … … 2257 2258 2258 2259 2260 #ifdef CONFIG_WITH_STRING_FUNCTIONS 2261 /* 2262 $(length string) 2263 2264 XXX: This doesn't take multibyte locales into account. 2265 */ 2266 static char * 2267 func_length (char *o, char **argv, const char *funcname UNUSED) 2268 { 2269 size_t len = strlen (argv[0]); 2270 return math_int_to_variable_buffer (o, len); 2271 } 2272 /* 2273 $(length-var var) 2274 2275 XXX: This doesn't take multibyte locales into account. 2276 */ 2277 static char * 2278 func_length_var (char *o, char **argv, const char *funcname UNUSED) 2279 { 2280 struct variable *var = lookup_variable (argv[0], strlen (argv[0])); 2281 return math_int_to_variable_buffer (o, var ? var->value_length : 0); 2282 } 2283 2284 2285 /* func_insert helper. */ 2286 static char * 2287 helper_insert_pad (char *o, size_t to_add, const char *pad, size_t pad_len) 2288 { 2289 while (to_add > 0) 2290 { 2291 size_t size = to_add > pad_len ? pad_len : to_add; 2292 o = variable_buffer_output (o, pad, size); 2293 to_add -= size; 2294 } 2295 return o; 2296 } 2297 2298 /* 2299 $(insert in, str[, n[, length[, pad]]]) 2300 2301 XXX: This doesn't take multibyte locales into account. 2302 */ 2303 static char * 2304 func_insert (char *o, char **argv, const char *funcname UNUSED) 2305 { 2306 const char *in = argv[0]; 2307 size_t in_len = strlen (in); 2308 const char *str = argv[1]; 2309 size_t str_len = strlen (str); 2310 math_int n = 0; 2311 math_int length = str_len; 2312 const char *pad = " "; 2313 size_t pad_len = 16; 2314 size_t i; 2315 2316 if (argv[2] != NULL) 2317 { 2318 n = math_int_from_string (argv[2]); 2319 if (n > 0) 2320 n--; /* one-origin */ 2321 else if (n == 0) 2322 n = str_len; /* append */ 2323 else 2324 { /* n < 0: from the end */ 2325 n = str_len + n; 2326 if (n < 0) 2327 n = 0; 2328 } 2329 if (n > 16*1024*1024) /* 16MB */ 2330 fatal (NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]); 2331 2332 if (argv[3] != NULL) 2333 { 2334 length = math_int_from_string (argv[3]); 2335 if (length < 0 || length > 16*1024*1024 /* 16MB */) 2336 fatal (NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]); 2337 2338 if (argv[4] != NULL) 2339 { 2340 const char *tmp = argv[4]; 2341 for (i = 0; tmp[i] == ' '; i++) 2342 /* nothing */; 2343 if (tmp[i] != '\0') 2344 { 2345 pad = argv[4]; 2346 pad_len = strlen (pad); 2347 } 2348 /* else: it was all default spaces. */ 2349 } 2350 } 2351 } 2352 2353 /* the head of the original string */ 2354 if (n > 0) 2355 { 2356 if (n <= str_len) 2357 o = variable_buffer_output (o, str, n); 2358 else 2359 { 2360 o = variable_buffer_output (o, str, str_len); 2361 o = helper_insert_pad (o, n - str_len, pad, pad_len); 2362 } 2363 } 2364 2365 /* insert the string */ 2366 if (length <= in_len) 2367 o = variable_buffer_output (o, in, length); 2368 else 2369 { 2370 o = variable_buffer_output (o, in, in_len); 2371 o = helper_insert_pad (o, length - in_len, pad, pad_len); 2372 } 2373 2374 /* the tail of the original string */ 2375 if (n < str_len) 2376 o = variable_buffer_output (o, str + n, str_len - n); 2377 2378 return o; 2379 } 2380 2381 2382 /* 2383 $(pos needle, haystack[, start]) 2384 $(lastpos needle, haystack[, start]) 2385 2386 XXX: This doesn't take multibyte locales into account. 2387 */ 2388 static char * 2389 func_pos (char *o, char **argv, const char *funcname UNUSED) 2390 { 2391 const char *needle = *argv[0] ? argv[0] : " "; 2392 size_t needle_len = strlen (needle); 2393 const char *haystack = argv[1]; 2394 size_t haystack_len = strlen (haystack); 2395 math_int start = 0; 2396 const char *hit; 2397 2398 if (argv[2] != NULL) 2399 { 2400 start = math_int_from_string (argv[2]); 2401 if (start > 0) 2402 start--; /* one-origin */ 2403 else if (start < 0) 2404 start = haystack_len + start; /* from the end */ 2405 if (start < 0 || start + needle_len > haystack_len) 2406 return math_int_to_variable_buffer (o, 0); 2407 } 2408 2409 /* do the searching */ 2410 if (funcname[0] != 'l') 2411 { /* pos */ 2412 if (needle_len == 1) 2413 hit = strchr (haystack + start, *needle); 2414 else 2415 hit = strstr (haystack + start, needle); 2416 } 2417 else 2418 { /* last pos */ 2419 int ch = *needle; 2420 size_t off = start + 1; 2421 2422 hit = NULL; 2423 while (off-- > 0) 2424 { 2425 if ( haystack[off] == ch 2426 && ( needle_len == 1 2427 || strncmp (&haystack[off], needle, needle_len) == 0)) 2428 { 2429 hit = haystack + off; 2430 break; 2431 } 2432 } 2433 } 2434 2435 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0); 2436 } 2437 2438 2439 /* 2440 $(substr str, start[, length[, pad]]) 2441 2442 XXX: This doesn't take multibyte locales into account. 2443 */ 2444 static char * 2445 func_substr (char *o, char **argv, const char *funcname UNUSED) 2446 { 2447 const char *str = argv[0]; 2448 size_t str_len = strlen (str); 2449 math_int start = math_int_from_string (argv[1]); 2450 math_int length = 0; 2451 const char *pad = NULL; 2452 size_t pad_len = 0; 2453 2454 if (argv[2] != NULL) 2455 { 2456 if (argv[3] != NULL) 2457 { 2458 pad = argv[3]; 2459 for (pad_len = 0; pad[pad_len] == ' '; pad_len++) 2460 /* nothing */; 2461 if (pad[pad_len] != '\0') 2462 pad_len = strlen (pad); 2463 else 2464 { 2465 pad = " "; 2466 pad_len = 16; 2467 } 2468 } 2469 length = math_int_from_string (argv[1]); 2470 if (length < 0 || (pad != NULL && length > 16*1024*1024 /* 16MB */)) 2471 fatal (NILF, _("$(substr ): length=%s is out of bounds\n"), argv[3]); 2472 if (length == 0) 2473 return o; 2474 } 2475 2476 /* adjust start and length. */ 2477 if (pad == NULL) 2478 { 2479 if (start > str_len) 2480 { 2481 start--; /* one-origin */ 2482 if (start >= str_len) 2483 return o; 2484 if (length == 0 || start + length > str_len) 2485 length = str_len - start; 2486 } 2487 else 2488 { 2489 start = str_len + start; 2490 if (start <= 0) 2491 { 2492 start += length; 2493 if (start <= 0) 2494 return o; 2495 length = start; 2496 start = 0; 2497 } 2498 else if (length == 0) 2499 length = str_len - start; 2500 } 2501 2502 o = variable_buffer_output (o, str + start, length); 2503 } 2504 else 2505 { 2506 if (start > str_len) 2507 { 2508 start--; /* one-origin */ 2509 if (start >= str_len) 2510 return length ? helper_insert_pad (o, length, pad, pad_len) : o; 2511 if (length == 0) 2512 length = str_len - start; 2513 } 2514 else 2515 { 2516 start = str_len + start; 2517 if (start <= 0) 2518 { 2519 if (start + length <= 0) 2520 return o; 2521 o = helper_insert_pad (o, -start, pad, pad_len); 2522 return variable_buffer_output (o, str, length + length); 2523 } 2524 if (length == 0) 2525 length = str_len - start; 2526 } 2527 if (start + length <= str_len) 2528 o = variable_buffer_output (o, str + start, length); 2529 else 2530 { 2531 o = variable_buffer_output (o, str + start, str_len - start); 2532 o = helper_insert_pad (o, start + length - start, pad, pad_len); 2533 } 2534 } 2535 2536 return o; 2537 } 2538 2539 2540 /* 2541 $(translate string, new-set[, old-set[, pad-char]]) 2542 2543 XXX: This doesn't take multibyte locales into account. 2544 */ 2545 static char * 2546 func_translate (char *o, char **argv, const char *funcname UNUSED) 2547 { 2548 const unsigned char *str = argv[0]; 2549 const unsigned char *new_set = argv[1]; 2550 const char *old_set = argv[2]; 2551 char trans_tab[1 << CHAR_BIT]; 2552 int i; 2553 char ch; 2554 2555 /* init the array. */ 2556 for (i = 0; i < (1 << CHAR_BIT); i++) 2557 trans_tab[i] = i; 2558 2559 while ( (i = *old_set) != '\0' 2560 && (ch = *new_set) != '\0') 2561 { 2562 trans_tab[i] = ch; 2563 old_set++; 2564 new_set++; 2565 } 2566 2567 if (i != '\0') 2568 { 2569 ch = '\0'; /* no padding == remove char */ 2570 if (argv[2] != NULL && argv[3] != NULL) 2571 { 2572 ch = argv[3][0]; 2573 if (ch && argv[3][1]) 2574 fatal (NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]); 2575 if (ch == '\0') /* no char == space */ 2576 ch = ' '; 2577 } 2578 while ((i = *old_set++) != '\0') 2579 trans_tab[i] = ch; 2580 } 2581 2582 /* do the translation */ 2583 while ((i = *str++) != '\0') 2584 { 2585 ch = trans_tab[i]; 2586 if (ch) 2587 o = variable_buffer_output (o, &ch, 1); 2588 } 2589 2590 return o; 2591 } 2592 #endif /* CONFIG_WITH_STRING_FUNCTIONS */ 2593 2594 2259 2595 #ifdef CONFIG_WITH_LAZY_DEPS_VARS 2260 2596 … … 4548 4884 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, 4549 4885 #endif 4886 #ifdef CONFIG_WITH_STRING_FUNCTIONS 4887 { STRING_SIZE_TUPLE("length"), 1, 1, 1, func_length}, 4888 { STRING_SIZE_TUPLE("length-var"), 1, 1, 1, func_length_var}, 4889 { STRING_SIZE_TUPLE("insert"), 3, 3, 1, func_insert}, 4890 { STRING_SIZE_TUPLE("pos"), 2, 3, 1, func_pos}, 4891 { STRING_SIZE_TUPLE("lastpos"), 2, 3, 1, func_pos}, 4892 { STRING_SIZE_TUPLE("substr"), 2, 4, 1, func_substr}, 4893 { STRING_SIZE_TUPLE("translate"), 2, 4, 1, func_translate}, 4894 #endif 4550 4895 #ifdef CONFIG_WITH_PRINTF 4551 4896 { STRING_SIZE_TUPLE("printf"), 1, 0, 1, kmk_builtin_func_printf}, -
trunk/src/kmk/variable.c
r2029 r2151 1205 1205 && (defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)) \ 1206 1206 && defined (CONFIG_WITH_COMMANDS_FUNC) \ 1207 && defined (CONFIG_WITH_PRINTF) \ 1208 && defined (CONFIG_WITH_STRING_FUNCTIONS) \ 1207 1209 && defined (KMK_HELPERS) 1208 1210 (void) define_variable ("KMK_FEATURES", 12, … … 1227 1229 " make-stats" 1228 1230 " commands" 1231 " printf" 1232 " length insert pos lastpos substr translate" 1229 1233 " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one kb-exp-tmpl " 1230 1234 , o_default, 0); … … 1289 1293 strcat (buf, " commands"); 1290 1294 # endif 1295 # if defined (CONFIG_WITH_PRINTF) 1296 strcat (buf, " printf"); 1297 # endif 1298 # if defined (CONFIG_WITH_STRING_FUNCTIONS) 1299 strcat (buf, " length insert pos lastpos substr translate"); 1300 # endif 1291 1301 # if defined (KMK_HELPERS) 1292 1302 strcat (buf, " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one kb-exp-tmpl");
Note:
See TracChangeset
for help on using the changeset viewer.