|
41 | 41 | * [getTsvFieldValue] - A convenience function when only a single value is needed |
42 | 42 | from an input line. |
43 | 43 |
|
44 | | - * [throwIfWindowsNewlineOnUnix] - A utility for Unix platform builds to detecting |
45 | | - Windows newlines in input. |
| 44 | + * [throwIfWindowsNewline] - A utility for detecting Windows newlines in input. |
46 | 45 | ) |
47 | 46 |
|
48 | 47 | Copyright (c) 2015-2020, eBay Inc. |
@@ -1426,103 +1425,98 @@ if (isSomeChar!C) |
1426 | 1425 | assertThrown(assertNotThrown!ConvException(getTsvFieldValue!double("abc\tdef", 2, '\t'))); |
1427 | 1426 | } |
1428 | 1427 |
|
1429 | | -/** [Yes|No.newlineWasRemoved] is a template parameter to throwIfWindowsNewlineOnUnix. |
1430 | | - * A Yes value indicates the Unix newline was already removed, as might be done via |
1431 | | - * std.File.byLine or similar mechanism. |
1432 | | - */ |
| 1428 | +/** |
| 1429 | +Yes|No.newlineWasRemoved is a template parameter to throwIfWindowsNewline. A Yes |
| 1430 | +value indicates the Unix newline was already removed, as might be done via |
| 1431 | +std.File.byLine or similar mechanism. |
| 1432 | +*/ |
1433 | 1433 | alias NewlineWasRemoved = Flag!"newlineWasRemoved"; |
1434 | 1434 |
|
1435 | 1435 | /** |
1436 | | -throwIfWindowsLineNewlineOnUnix is used to throw an exception if a Windows/DOS |
1437 | | -line ending is found on a build compiled for a Unix platform. This is used by |
1438 | | -the TSV Utilities to detect Window/DOS line endings and terminate processing |
1439 | | -with an error message to the user. |
1440 | | - */ |
1441 | | -void throwIfWindowsNewlineOnUnix |
| 1436 | +throwIfWindowsLineNewline throws an exception if the 'line' argument ends with a |
| 1437 | +Windows/DOS line ending. This is used by TSV Utilities tools to detect Window/DOS |
| 1438 | +line endings and terminate processing with an error message to the user. |
| 1439 | +
|
| 1440 | +The 'nlWasRemoved' template parameter can be used if a Unix newline character was |
| 1441 | +already removed. In this case the CR character from a Windows CRLF remains and can be |
| 1442 | +detected. This is useful when reading files in binary mode, stripping Unix newlines. |
| 1443 | +*/ |
| 1444 | +void throwIfWindowsNewline |
1442 | 1445 | (NewlineWasRemoved nlWasRemoved = Yes.newlineWasRemoved) |
1443 | 1446 | (const char[] line, const char[] filename, size_t lineNum) |
1444 | 1447 | { |
1445 | | - version(Posix) |
| 1448 | + static if (nlWasRemoved) |
1446 | 1449 | { |
1447 | | - static if (nlWasRemoved) |
1448 | | - { |
1449 | | - immutable bool hasWindowsLineEnding = line.length != 0 && line[$ - 1] == '\r'; |
1450 | | - } |
1451 | | - else |
1452 | | - { |
1453 | | - immutable bool hasWindowsLineEnding = |
1454 | | - line.length > 1 && |
1455 | | - line[$ - 2] == '\r' && |
1456 | | - line[$ - 1] == '\n'; |
1457 | | - } |
| 1450 | + immutable bool hasWindowsLineEnding = line.length != 0 && line[$ - 1] == '\r'; |
| 1451 | + } |
| 1452 | + else |
| 1453 | + { |
| 1454 | + immutable bool hasWindowsLineEnding = |
| 1455 | + line.length > 1 && |
| 1456 | + line[$ - 2] == '\r' && |
| 1457 | + line[$ - 1] == '\n'; |
| 1458 | + } |
1458 | 1459 |
|
1459 | | - if (hasWindowsLineEnding) |
1460 | | - { |
1461 | | - import std.format; |
1462 | | - throw new Exception( |
1463 | | - format("Windows/DOS line ending found. Convert file to Unix newlines before processing (e.g. 'dos2unix').\n File: %s, Line: %s", |
1464 | | - (filename == "-") ? "Standard Input" : filename, lineNum)); |
1465 | | - } |
| 1460 | + if (hasWindowsLineEnding) |
| 1461 | + { |
| 1462 | + import std.format; |
| 1463 | + throw new Exception( |
| 1464 | + format("Windows/DOS line ending found. Convert file to Unix newlines before processing (e.g. 'dos2unix').\n File: %s, Line: %s", |
| 1465 | + (filename == "-") ? "Standard Input" : filename, lineNum)); |
1466 | 1466 | } |
1467 | 1467 | } |
1468 | 1468 |
|
1469 | | -// throwIfWindowsNewlineOnUnix |
| 1469 | +// throwIfWindowsNewline |
1470 | 1470 | @safe unittest |
1471 | 1471 | { |
1472 | | - /* Note: Currently only building on Posix. Need to add non-Posix test cases |
1473 | | - * if Windows builds are ever done. |
1474 | | - */ |
1475 | | - version(Posix) |
1476 | | - { |
1477 | | - import std.exception; |
| 1472 | + import std.exception; |
1478 | 1473 |
|
1479 | | - assertNotThrown(throwIfWindowsNewlineOnUnix("", "afile.tsv", 1)); |
1480 | | - assertNotThrown(throwIfWindowsNewlineOnUnix("a", "afile.tsv", 2)); |
1481 | | - assertNotThrown(throwIfWindowsNewlineOnUnix("ab", "afile.tsv", 3)); |
1482 | | - assertNotThrown(throwIfWindowsNewlineOnUnix("abc", "afile.tsv", 4)); |
| 1474 | + assertNotThrown(throwIfWindowsNewline("", "afile.tsv", 1)); |
| 1475 | + assertNotThrown(throwIfWindowsNewline("a", "afile.tsv", 2)); |
| 1476 | + assertNotThrown(throwIfWindowsNewline("ab", "afile.tsv", 3)); |
| 1477 | + assertNotThrown(throwIfWindowsNewline("abc", "afile.tsv", 4)); |
1483 | 1478 |
|
1484 | | - assertThrown(throwIfWindowsNewlineOnUnix("\r", "afile.tsv", 1)); |
1485 | | - assertThrown(throwIfWindowsNewlineOnUnix("a\r", "afile.tsv", 2)); |
1486 | | - assertThrown(throwIfWindowsNewlineOnUnix("ab\r", "afile.tsv", 3)); |
1487 | | - assertThrown(throwIfWindowsNewlineOnUnix("abc\r", "afile.tsv", 4)); |
| 1479 | + assertThrown(throwIfWindowsNewline("\r", "afile.tsv", 1)); |
| 1480 | + assertThrown(throwIfWindowsNewline("a\r", "afile.tsv", 2)); |
| 1481 | + assertThrown(throwIfWindowsNewline("ab\r", "afile.tsv", 3)); |
| 1482 | + assertThrown(throwIfWindowsNewline("abc\r", "afile.tsv", 4)); |
1488 | 1483 |
|
1489 | | - assertNotThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("\n", "afile.tsv", 1)); |
1490 | | - assertNotThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("a\n", "afile.tsv", 2)); |
1491 | | - assertNotThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("ab\n", "afile.tsv", 3)); |
1492 | | - assertNotThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("abc\n", "afile.tsv", 4)); |
| 1484 | + assertNotThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("\n", "afile.tsv", 1)); |
| 1485 | + assertNotThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("a\n", "afile.tsv", 2)); |
| 1486 | + assertNotThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("ab\n", "afile.tsv", 3)); |
| 1487 | + assertNotThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("abc\n", "afile.tsv", 4)); |
1493 | 1488 |
|
1494 | | - assertThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("\r\n", "afile.tsv", 5)); |
1495 | | - assertThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("a\r\n", "afile.tsv", 6)); |
1496 | | - assertThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("ab\r\n", "afile.tsv", 7)); |
1497 | | - assertThrown(throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("abc\r\n", "afile.tsv", 8)); |
| 1489 | + assertThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("\r\n", "afile.tsv", 5)); |
| 1490 | + assertThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("a\r\n", "afile.tsv", 6)); |
| 1491 | + assertThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("ab\r\n", "afile.tsv", 7)); |
| 1492 | + assertThrown(throwIfWindowsNewline!(No.newlineWasRemoved)("abc\r\n", "afile.tsv", 8)); |
1498 | 1493 |
|
1499 | | - /* Standard Input formatting. */ |
1500 | | - import std.algorithm : endsWith; |
1501 | | - bool exceptionCaught = false; |
| 1494 | + /* Standard Input formatting. */ |
| 1495 | + import std.algorithm : endsWith; |
| 1496 | + bool exceptionCaught = false; |
1502 | 1497 |
|
1503 | | - try (throwIfWindowsNewlineOnUnix("\r", "-", 99)); |
1504 | | - catch (Exception e) |
1505 | | - { |
1506 | | - assert(e.msg.endsWith("File: Standard Input, Line: 99")); |
1507 | | - exceptionCaught = true; |
1508 | | - } |
1509 | | - finally |
1510 | | - { |
1511 | | - assert(exceptionCaught); |
1512 | | - exceptionCaught = false; |
1513 | | - } |
| 1498 | + try (throwIfWindowsNewline("\r", "-", 99)); |
| 1499 | + catch (Exception e) |
| 1500 | + { |
| 1501 | + assert(e.msg.endsWith("File: Standard Input, Line: 99")); |
| 1502 | + exceptionCaught = true; |
| 1503 | + } |
| 1504 | + finally |
| 1505 | + { |
| 1506 | + assert(exceptionCaught); |
| 1507 | + exceptionCaught = false; |
| 1508 | + } |
1514 | 1509 |
|
1515 | | - try (throwIfWindowsNewlineOnUnix!(No.newlineWasRemoved)("\r\n", "-", 99)); |
1516 | | - catch (Exception e) |
1517 | | - { |
1518 | | - assert(e.msg.endsWith("File: Standard Input, Line: 99")); |
1519 | | - exceptionCaught = true; |
1520 | | - } |
1521 | | - finally |
1522 | | - { |
1523 | | - assert(exceptionCaught); |
1524 | | - exceptionCaught = false; |
1525 | | - } |
| 1510 | + try (throwIfWindowsNewline!(No.newlineWasRemoved)("\r\n", "-", 99)); |
| 1511 | + catch (Exception e) |
| 1512 | + { |
| 1513 | + assert(e.msg.endsWith("File: Standard Input, Line: 99")); |
| 1514 | + exceptionCaught = true; |
| 1515 | + } |
| 1516 | + finally |
| 1517 | + { |
| 1518 | + assert(exceptionCaught); |
| 1519 | + exceptionCaught = false; |
1526 | 1520 | } |
1527 | 1521 | } |
1528 | 1522 |
|
|
0 commit comments