Skip to content

Commit 1792b1c

Browse files
committed
FEATURE: add unix2dos and dos2unix utilities to use in windows
1 parent 15a5987 commit 1792b1c

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

dos2unix.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
DOS to Unix line ending converter utility.
5+
6+
This module provides functionality to convert text files from DOS/Windows (CRLF)
7+
to Unix (LF) line endings. Binary files are automatically skipped.
8+
9+
This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator
10+
11+
SPDX-FileCopyrightText: 2024-2025 Amilcar do Carmo Lucas <[email protected]>
12+
13+
SPDX-License-Identifier: GPL-3.0-or-later
14+
"""
15+
16+
import logging
17+
import sys
18+
from glob import glob
19+
from pathlib import Path
20+
21+
# pylint: disable=duplicate-code
22+
23+
# Configure logging
24+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
25+
logger = logging.getLogger(__name__)
26+
27+
28+
def is_binary(filepath: Path) -> bool:
29+
"""
30+
Check if a file is binary by reading its first 8192 bytes.
31+
32+
Returns True if the file appears to be binary, False otherwise.
33+
"""
34+
chunk_size = 8192
35+
try:
36+
with open(filepath, "rb") as file:
37+
chunk = file.read(chunk_size)
38+
# Check for null bytes and other binary characters
39+
textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F})
40+
return bool(chunk.translate(None, textchars))
41+
except OSError as e:
42+
logger.error("Failed to read file %s: %s", filepath, str(e))
43+
return True # If we can't read the file, treat it as binary to be safe
44+
45+
46+
def dos2unix(filepath: str) -> None:
47+
"""Convert DOS line endings (CRLF) to Unix line endings (LF)."""
48+
try:
49+
path = Path(filepath)
50+
51+
if is_binary(path):
52+
logger.warning("Skipping binary file: %s", filepath)
53+
return
54+
55+
# Read content in binary mode
56+
content = path.read_bytes()
57+
58+
# Replace \r\n with \n
59+
content = content.replace(b"\r\n", b"\n")
60+
61+
# Write back in binary mode
62+
path.write_bytes(content)
63+
logger.info("Successfully converted %s", filepath)
64+
65+
except OSError as e:
66+
logger.error("Error processing %s: %s", filepath, str(e))
67+
sys.exit(1)
68+
69+
70+
if __name__ == "__main__":
71+
if len(sys.argv) != 2:
72+
logger.error("Usage: dos2unix.py <filepath or pattern>")
73+
sys.exit(1)
74+
75+
pattern = sys.argv[1]
76+
files = glob(pattern)
77+
78+
if not files:
79+
logger.error("No files found matching pattern: %s", pattern)
80+
sys.exit(1)
81+
82+
for filename in files:
83+
dos2unix(filename)

unix2dos.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Unix to DOS line ending converter utility.
5+
6+
This module provides functionality to convert text files from Unix (LF)
7+
to DOS/Windows (CRLF) line endings. Binary files are automatically skipped.
8+
9+
This file is part of Ardupilot methodic configurator. https://github.com/ArduPilot/MethodicConfigurator
10+
11+
SPDX-FileCopyrightText: 2024-2025 Amilcar do Carmo Lucas <[email protected]>
12+
13+
SPDX-License-Identifier: GPL-3.0-or-later
14+
"""
15+
16+
import logging
17+
import sys
18+
from glob import glob
19+
from pathlib import Path
20+
21+
# pylint: disable=duplicate-code
22+
23+
# Configure logging
24+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
25+
logger = logging.getLogger(__name__)
26+
27+
28+
def is_binary(filepath: Path) -> bool:
29+
"""
30+
Check if a file is binary by reading its first 8192 bytes.
31+
32+
Returns True if the file appears to be binary, False otherwise.
33+
"""
34+
chunk_size = 8192
35+
try:
36+
with open(filepath, "rb") as file:
37+
chunk = file.read(chunk_size)
38+
# Check for null bytes and other binary characters
39+
textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F})
40+
return bool(chunk.translate(None, textchars))
41+
except OSError as e:
42+
logger.error("Failed to read file %s: %s", filepath, str(e))
43+
return True # If we can't read the file, treat it as binary to be safe
44+
45+
46+
def unix2dos(filepath: str) -> None:
47+
"""Convert Unix line endings (LF) to DOS line endings (CRLF)."""
48+
try:
49+
path = Path(filepath)
50+
51+
if is_binary(path):
52+
logger.warning("Skipping binary file: %s", filepath)
53+
return
54+
55+
# Read content in binary mode
56+
content = path.read_bytes()
57+
58+
# Replace \n with \r\n, but avoid double conversion
59+
content = content.replace(b"\r\n", b"\n") # Normalize to \n first
60+
content = content.replace(b"\n", b"\r\n") # Convert to \r\n
61+
62+
# Write back in binary mode
63+
path.write_bytes(content)
64+
logger.info("Successfully converted %s", filepath)
65+
66+
except OSError as e:
67+
logger.error("Error processing %s: %s", filepath, str(e))
68+
sys.exit(1)
69+
70+
71+
if __name__ == "__main__":
72+
if len(sys.argv) != 2:
73+
logger.error("Usage: unix2dos.py <filepath or pattern>")
74+
sys.exit(1)
75+
76+
pattern = sys.argv[1]
77+
files = glob(pattern)
78+
79+
if not files:
80+
logger.error("No files found matching pattern: %s", pattern)
81+
sys.exit(1)
82+
83+
for filename in files:
84+
unix2dos(filename)

0 commit comments

Comments
 (0)