| 1266 | | FUNCTION(fun_setunion) |
|---|
| 1267 | | { |
|---|
| 1268 | | char sep; |
|---|
| 1269 | | char **a1, **a2; |
|---|
| 1270 | | char *tempbuff; |
|---|
| 1271 | | int n1, i, a; |
|---|
| 1272 | | char *sort_type = ALPHANUM_LIST; |
|---|
| 1273 | | char *osep = NULL, osepd[2] = { '\0', '\0' }; |
|---|
| 1274 | | |
|---|
| 1275 | | /* if no lists, then no work */ |
|---|
| 1276 | | if (!*args[0] && !*args[1]) |
|---|
| 1277 | | return; |
|---|
| 1278 | | |
|---|
| 1279 | | if (!delim_check(buff, bp, nargs, args, 3, &sep)) |
|---|
| 1280 | | return; |
|---|
| 1281 | | |
|---|
| 1282 | | tempbuff = (char *) mush_malloc((BUFFER_LEN * 2) + 4, "string"); |
|---|
| 1283 | | a1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); |
|---|
| 1284 | | a2 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); |
|---|
| 1285 | | if (!tempbuff || !a1 || !a2) |
|---|
| 1286 | | mush_panic("Unable to allocate memory in fun_setunion"); |
|---|
| 1287 | | /* Concat both lists, make array, sort */ |
|---|
| 1288 | | if (!*args[0]) |
|---|
| 1289 | | memcpy(tempbuff, args[1], arglens[1] + 1); |
|---|
| 1290 | | else if (!*args[1]) |
|---|
| 1291 | | memcpy(tempbuff, args[0], arglens[0] + 1); |
|---|
| 1292 | | else |
|---|
| 1293 | | sprintf(tempbuff, "%s%c%s", args[0], sep, args[1]); |
|---|
| 1294 | | n1 = list2arr(a1, MAX_SORTSIZE, tempbuff, sep); |
|---|
| 1295 | | |
|---|
| 1296 | | if (nargs < 4) { |
|---|
| 1297 | | osepd[0] = sep; |
|---|
| 1298 | | osep = osepd; |
|---|
| 1299 | | } else if (nargs == 4) { |
|---|
| 1300 | | sort_type = get_list_type_noauto(args, nargs, 4); |
|---|
| 1301 | | if (sort_type == UNKNOWN_LIST) { |
|---|
| 1302 | | sort_type = ALPHANUM_LIST; |
|---|
| 1303 | | osep = args[3]; |
|---|
| 1304 | | } else { |
|---|
| 1305 | | osepd[0] = sep; |
|---|
| 1306 | | osep = osepd; |
|---|
| 1307 | | } |
|---|
| 1308 | | } else if (nargs == 5) { |
|---|
| 1309 | | sort_type = get_list_type(args, nargs, 4, a1, n1); |
|---|
| 1310 | | osep = args[4]; |
|---|
| 1311 | | } |
|---|
| 1312 | | |
|---|
| 1313 | | do_gensort(executor, a1, NULL, n1, sort_type); |
|---|
| 1314 | | |
|---|
| 1315 | | /* Strip the duplicates and make a2 contain the list */ |
|---|
| 1316 | | a = 0; |
|---|
| 1317 | | for (i = 0; i < n1; i++) { |
|---|
| 1318 | | if (((a == 0) || (gencomp(executor, a1[i], a2[a - 1], sort_type) != 0))) { |
|---|
| 1319 | | a2[a] = a1[i]; |
|---|
| 1320 | | a++; |
|---|
| 1321 | | } |
|---|
| 1322 | | } |
|---|
| 1323 | | |
|---|
| 1324 | | /* Return our sorted result */ |
|---|
| 1325 | | arr2list(a2, a, buff, bp, osep); |
|---|
| 1326 | | mush_free((Malloc_t) tempbuff, "string"); |
|---|
| 1327 | | mush_free((Malloc_t) a1, "ptrarray"); |
|---|
| 1328 | | mush_free((Malloc_t) a2, "ptrarray"); |
|---|
| 1329 | | } |
|---|
| 1330 | | |
|---|
| 1331 | | /* ARGSUSED */ |
|---|
| | 1381 | FUNCTION(fun_setunion) |
|---|
| | 1382 | { |
|---|
| | 1383 | char sep; |
|---|
| | 1384 | char **a1, **a2; |
|---|
| | 1385 | int n1, n2, x1, x2, val; |
|---|
| | 1386 | int lastx1, lastx2, found; |
|---|
| | 1387 | char *sort_type = ALPHANUM_LIST; |
|---|
| | 1388 | int osepl = 0; |
|---|
| | 1389 | char *osep = NULL, osepd[2] = { '\0', '\0' }; |
|---|
| | 1390 | |
|---|
| | 1391 | /* if no lists, then no work */ |
|---|
| | 1392 | if (!*args[0] && !*args[1]) |
|---|
| | 1393 | return; |
|---|
| | 1394 | |
|---|
| | 1395 | if (!delim_check(buff, bp, nargs, args, 3, &sep)) |
|---|
| | 1396 | return; |
|---|
| | 1397 | |
|---|
| | 1398 | a1 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); |
|---|
| | 1399 | a2 = (char **) mush_malloc(MAX_SORTSIZE * sizeof(char *), "ptrarray"); |
|---|
| | 1400 | if (!a1 || !a2) |
|---|
| | 1401 | mush_panic("Unable to allocate memory in fun_setunion"); |
|---|
| | 1402 | |
|---|
| | 1403 | /* make arrays out of the lists */ |
|---|
| | 1404 | n1 = list2arr(a1, MAX_SORTSIZE, args[0], sep); |
|---|
| | 1405 | n2 = list2arr(a2, MAX_SORTSIZE, args[1], sep); |
|---|
| | 1406 | |
|---|
| | 1407 | if (nargs < 4) { |
|---|
| | 1408 | osepd[0] = sep; |
|---|
| | 1409 | osep = osepd; |
|---|
| | 1410 | if (sep) |
|---|
| | 1411 | osepl = 1; |
|---|
| | 1412 | } else if (nargs == 4) { |
|---|
| | 1413 | sort_type = get_list_type_noauto(args, nargs, 4); |
|---|
| | 1414 | if (sort_type == UNKNOWN_LIST) { |
|---|
| | 1415 | sort_type = ALPHANUM_LIST; |
|---|
| | 1416 | osep = args[3]; |
|---|
| | 1417 | osepl = arglens[3]; |
|---|
| | 1418 | } else { |
|---|
| | 1419 | osepd[0] = sep; |
|---|
| | 1420 | osep = osepd; |
|---|
| | 1421 | if (sep) |
|---|
| | 1422 | osepl = 1; |
|---|
| | 1423 | } |
|---|
| | 1424 | } else if (nargs == 5) { |
|---|
| | 1425 | sort_type = get_list_type(args, nargs, 4, a1, n1); |
|---|
| | 1426 | osep = args[4]; |
|---|
| | 1427 | osepl = arglens[4]; |
|---|
| | 1428 | } |
|---|
| | 1429 | /* sort each array */ |
|---|
| | 1430 | do_gensort(executor, a1, NULL, n1, sort_type); |
|---|
| | 1431 | do_gensort(executor, a2, NULL, n2, sort_type); |
|---|
| | 1432 | |
|---|
| | 1433 | /* get values for the union, in order, skipping duplicates */ |
|---|
| | 1434 | lastx1 = lastx2 = -1; |
|---|
| | 1435 | found = x1 = x2 = 0; |
|---|
| | 1436 | if (n1 == 1 && !*a1[0]) |
|---|
| | 1437 | n1 = 0; |
|---|
| | 1438 | if (n2 == 1 && !*a2[0]) |
|---|
| | 1439 | n2 = 0; |
|---|
| | 1440 | while ((x1 < n1) || (x2 < n2)) { |
|---|
| | 1441 | /* If we've already copied off something from a1, and our current |
|---|
| | 1442 | * look at a1 is the same element, or we've copied from a2 and |
|---|
| | 1443 | * our current look at a1 is the same element, skip forward in a1. |
|---|
| | 1444 | */ |
|---|
| | 1445 | if (x1 < n1 && lastx1 >= 0) { |
|---|
| | 1446 | val = gencomp(executor, a1[lastx1], a1[x1], sort_type); |
|---|
| | 1447 | if (val == 0) { |
|---|
| | 1448 | x1++; |
|---|
| | 1449 | continue; |
|---|
| | 1450 | } |
|---|
| | 1451 | } |
|---|
| | 1452 | if (x1 < n1 && lastx2 >= 0) { |
|---|
| | 1453 | val = gencomp(executor, a2[lastx2], a1[x1], sort_type); |
|---|
| | 1454 | if (val == 0) { |
|---|
| | 1455 | x1++; |
|---|
| | 1456 | continue; |
|---|
| | 1457 | } |
|---|
| | 1458 | } |
|---|
| | 1459 | if (x2 < n2 && lastx1 >= 0) { |
|---|
| | 1460 | val = gencomp(executor, a1[lastx1], a2[x2], sort_type); |
|---|
| | 1461 | if (val == 0) { |
|---|
| | 1462 | x2++; |
|---|
| | 1463 | continue; |
|---|
| | 1464 | } |
|---|
| | 1465 | } |
|---|
| | 1466 | if (x2 < n2 && lastx2 >= 0) { |
|---|
| | 1467 | val = gencomp(executor, a2[lastx2], a2[x2], sort_type); |
|---|
| | 1468 | if (val == 0) { |
|---|
| | 1469 | x2++; |
|---|
| | 1470 | continue; |
|---|
| | 1471 | } |
|---|
| | 1472 | } |
|---|
| | 1473 | if (x1 >= n1) { |
|---|
| | 1474 | /* Just copy off the rest of a2 */ |
|---|
| | 1475 | if (x2 < n2) { |
|---|
| | 1476 | if (found) |
|---|
| | 1477 | safe_strl(osep, osepl, buff, bp); |
|---|
| | 1478 | safe_str(a2[x2], buff, bp); |
|---|
| | 1479 | lastx2 = x2; |
|---|
| | 1480 | x2++; |
|---|
| | 1481 | found = 1; |
|---|
| | 1482 | } |
|---|
| | 1483 | } else if (x2 >= n2) { |
|---|
| | 1484 | /* Just copy off the rest of a1 */ |
|---|
| | 1485 | if (x1 < n1) { |
|---|
| | 1486 | if (found) |
|---|
| | 1487 | safe_strl(osep, osepl, buff, bp); |
|---|
| | 1488 | safe_str(a1[x1], buff, bp); |
|---|
| | 1489 | lastx1 = x1; |
|---|
| | 1490 | x1++; |
|---|
| | 1491 | found = 1; |
|---|
| | 1492 | } |
|---|
| | 1493 | } else { |
|---|
| | 1494 | /* At this point, we're merging. Take the lower of the two. */ |
|---|
| | 1495 | val = gencomp(executor, a1[x1], a2[x2], sort_type); |
|---|
| | 1496 | if (val <= 0) { |
|---|
| | 1497 | if (found) |
|---|
| | 1498 | safe_strl(osep, osepl, buff, bp); |
|---|
| | 1499 | safe_str(a1[x1], buff, bp); |
|---|
| | 1500 | lastx1 = x1; |
|---|
| | 1501 | x1++; |
|---|
| | 1502 | found = 1; |
|---|
| | 1503 | } else { |
|---|
| | 1504 | if (found) |
|---|
| | 1505 | safe_strl(osep, osepl, buff, bp); |
|---|
| | 1506 | safe_str(a2[x2], buff, bp); |
|---|
| | 1507 | lastx2 = x2; |
|---|
| | 1508 | x2++; |
|---|
| | 1509 | found = 1; |
|---|
| | 1510 | } |
|---|
| | 1511 | } |
|---|
| | 1512 | } |
|---|
| | 1513 | mush_free((Malloc_t) a1, "ptrarray"); |
|---|
| | 1514 | mush_free((Malloc_t) a2, "ptrarray"); |
|---|
| | 1515 | } |
|---|
| | 1516 | |
|---|
| | 1517 | /* ARGSUSED */ |
|---|