September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -1,52 +1,25 @@
|
|||
text
|
||||
cdp(...)
|
||||
{
|
||||
integer e;
|
||||
record r;
|
||||
integer i;
|
||||
text s;
|
||||
|
||||
i = -count();
|
||||
while (i) {
|
||||
r_add(r, $i, 0);
|
||||
i += 1;
|
||||
ucall(r_add, 1, r, 0);
|
||||
|
||||
if (~r) {
|
||||
s = r.low;
|
||||
s = s.cut(0, e = b_trace(s, prefix(s, r.high), '/'));
|
||||
s = ~s || e == -1 ? s : "/";
|
||||
}
|
||||
|
||||
if (r_size(r)) {
|
||||
integer c;
|
||||
text v;
|
||||
|
||||
r_first(r, s);
|
||||
r_last(r, v);
|
||||
|
||||
i = 0;
|
||||
while ((c = s[i]) == v[i] && c) {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (!c && v[i] == '/') {
|
||||
} else {
|
||||
while (i && s[i - 1] != '/') {
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 < i && s[i - 1] == '/') {
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
s = cut(s, 0, i);
|
||||
}
|
||||
|
||||
return s;
|
||||
s;
|
||||
}
|
||||
|
||||
integer
|
||||
main(void)
|
||||
{
|
||||
o_text(cdp("/home/user1/tmp/coverage/test",
|
||||
"/home/user1/tmp/covert/operator",
|
||||
"/home/user1/tmp/coven/members"));
|
||||
o_byte('\n');
|
||||
o_(cdp("/home/user1/tmp/coverage/test",
|
||||
"/home/user1/tmp/covert/operator",
|
||||
"/home/user1/tmp/coven/members"), "\n");
|
||||
|
||||
return 0;
|
||||
0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
' compile: fbc.exe -s console cdp.bas
|
||||
|
||||
Function CommonDirectoryPath Cdecl(count As Integer, ...) As String
|
||||
Dim As String Path(), s
|
||||
Dim As Integer i, j, k = 1
|
||||
Dim arg As Any Ptr
|
||||
Const PATH_SEPARATOR As String = "/"
|
||||
|
||||
arg = va_first()
|
||||
ReDim Preserve Path(1 To count)
|
||||
For i = 1 To count
|
||||
Path(i) = *Va_Arg(arg, ZString Ptr)
|
||||
Print Path(i)
|
||||
arg = va_next(arg, ZString Ptr)
|
||||
Next i
|
||||
|
||||
Do
|
||||
For i = 1 To count
|
||||
If i > 1 Then
|
||||
If InStr(k, Path(i), PATH_SEPARATOR) <> j Then
|
||||
Exit Do
|
||||
ElseIf Left(Path(i), j) <> Left(Path(1), j) Then
|
||||
Exit Do
|
||||
End If
|
||||
Else
|
||||
j = InStr(k, Path(i), PATH_SEPARATOR)
|
||||
If j = 0 Then
|
||||
Exit Do
|
||||
End If
|
||||
End If
|
||||
Next i
|
||||
s = Left(Path(1), j + CLng(k <> 1))
|
||||
k = j + 1
|
||||
Loop
|
||||
Return s
|
||||
|
||||
End Function
|
||||
|
||||
|
||||
' testing the above function
|
||||
|
||||
Print CommonDirectoryPath( 3, _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members") & " <- common"
|
||||
Print
|
||||
|
||||
Print CommonDirectoryPath( 4, _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members", _
|
||||
"/home/user1/abc/coven/members") & " <- common"
|
||||
Print
|
||||
|
||||
Print CommonDirectoryPath( 3, _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/hope/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members") & " <- common"
|
||||
Print
|
||||
|
||||
' empty keyboard buffer
|
||||
While Inkey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import Data.List (transpose, intercalate)
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
cdp :: [String] -> String
|
||||
cdp xs
|
||||
| null xs = []
|
||||
| otherwise =
|
||||
(intercalate "/" .
|
||||
fmap head . takeWhile same . transpose . fmap (splitOn "/"))
|
||||
xs
|
||||
|
||||
same
|
||||
:: Eq a
|
||||
=> [a] -> Bool
|
||||
same [] = True
|
||||
same (x:xs) = all (x ==) xs
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
(putStrLn . cdp)
|
||||
[ "/home/user1/tmp/coverage/test"
|
||||
, "/home/user1/tmp/covert/operator"
|
||||
, "/home/user1/tmp/coven/members"
|
||||
]
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Given an array of strings, return an array of arrays, containing the
|
||||
* strings split at the given separator
|
||||
* @param {!Array<!string>} a
|
||||
* @param {string} sep
|
||||
* @returns {!Array<!Array<string>>}
|
||||
*/
|
||||
const splitStrings = (a, sep = '/') => a.map(i => i.split(sep));
|
||||
|
||||
/**
|
||||
* Given an index number, return a function that takes an array and returns the
|
||||
* element at the given index
|
||||
* @param {number} i
|
||||
* @return {function(!Array<*>): *}
|
||||
*/
|
||||
const elAt = i => a => a[i];
|
||||
|
||||
/**
|
||||
* Transpose an array of arrays:
|
||||
* Example:
|
||||
* [['a', 'b', 'c'], ['A', 'B', 'C'], [1, 2, 3]] ->
|
||||
* [['a', 'A', 1], ['b', 'B', 2], ['c', 'C', 3]]
|
||||
* @param {!Array<!Array<*>>} a
|
||||
* @return {!Array<!Array<*>>}
|
||||
*/
|
||||
const rotate = a => a[0].map((e, i) => a.map(elAt(i)));
|
||||
|
||||
/**
|
||||
* Checks of all the elements in the array are the same.
|
||||
* @param {!Array<*>} arr
|
||||
* @return {boolean}
|
||||
*/
|
||||
const allElementsEqual = arr => arr.every(e => e === arr[0]);
|
||||
|
||||
|
||||
const commonPath = (input, sep = '/') => rotate(splitStrings(input, sep))
|
||||
.filter(allElementsEqual).map(elAt(0)).join(sep);
|
||||
|
||||
const cdpInput = [
|
||||
'/home/user1/tmp/coverage/test',
|
||||
'/home/user1/tmp/covert/operator',
|
||||
'/home/user1/tmp/coven/members',
|
||||
];
|
||||
|
||||
console.log(`Common path is: ${commonPath(cdpInput)}`);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
sub common_prefix {
|
||||
my $sep = shift;
|
||||
my $paths = join "\0", map { $_.$sep } @_;
|
||||
$paths =~ /^ ( [^\0]* ) $sep [^\0]* (?: \0 \1 $sep [^\0]* )* $/sx;
|
||||
$paths =~ /^ ( [^\0]* ) $sep [^\0]* (?: \0 \1 $sep [^\0]* )* $/x;
|
||||
return $1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ sub common_prefix {
|
|||
my ($sep, @paths) = @_;
|
||||
my %prefixes;
|
||||
|
||||
foreach (@paths) {
|
||||
do { ++$prefixes{$_} } while s/$sep [^$sep]* $//g
|
||||
for (@paths) {
|
||||
do { ++$prefixes{$_} } while s/$sep [^$sep]* $//x
|
||||
}
|
||||
|
||||
return first { $prefixes{$_} == @paths } reverse sort keys %prefixes;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
#COMPILE EXE
|
||||
#DIM ALL
|
||||
#COMPILER PBCC 6
|
||||
$PATH_SEPARATOR = "/"
|
||||
|
||||
FUNCTION CommonDirectoryPath(Paths() AS STRING) AS STRING
|
||||
LOCAL s AS STRING
|
||||
LOCAL i, j, k AS LONG
|
||||
k = 1
|
||||
DO
|
||||
FOR i = 0 TO UBOUND(Paths)
|
||||
IF i THEN
|
||||
IF INSTR(k, Paths(i), $PATH_SEPARATOR) <> j THEN
|
||||
EXIT DO
|
||||
ELSEIF LEFT$(Paths(i), j) <> LEFT$(Paths(0), j) THEN
|
||||
EXIT DO
|
||||
END IF
|
||||
ELSE
|
||||
j = INSTR(k, Paths(i), $PATH_SEPARATOR)
|
||||
IF j = 0 THEN
|
||||
EXIT DO
|
||||
END IF
|
||||
END IF
|
||||
NEXT i
|
||||
s = LEFT$(Paths(0), j + CLNG(k <> 1))
|
||||
k = j + 1
|
||||
LOOP
|
||||
FUNCTION = s
|
||||
|
||||
END FUNCTION
|
||||
|
||||
|
||||
FUNCTION PBMAIN () AS LONG
|
||||
|
||||
' testing the above function
|
||||
|
||||
LOCAL s() AS STRING
|
||||
LOCAL i AS LONG
|
||||
|
||||
REDIM s(0 TO 2)
|
||||
ARRAY ASSIGN s() = "/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members"
|
||||
FOR i = 0 TO UBOUND(s()): CON.PRINT s(i): NEXT i
|
||||
CON.PRINT CommonDirectoryPath(s()) & " <- common"
|
||||
CON.PRINT
|
||||
|
||||
REDIM s(0 TO 3)
|
||||
ARRAY ASSIGN s() = "/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members", _
|
||||
"/home/user1/abc/coven/members"
|
||||
FOR i = 0 TO UBOUND(s()): CON.PRINT s(i): NEXT i
|
||||
CON.PRINT CommonDirectoryPath(s()) & " <- common"
|
||||
CON.PRINT
|
||||
|
||||
REDIM s(0 TO 2)
|
||||
ARRAY ASSIGN s() = "/home/user1/tmp/coverage/test", _
|
||||
"/hope/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members"
|
||||
FOR i = 0 TO UBOUND(s()): CON.PRINT s(i): NEXT i
|
||||
CON.PRINT CommonDirectoryPath(s()) & " <- common"
|
||||
CON.PRINT
|
||||
|
||||
CON.PRINT "hit any key to end program"
|
||||
CON.WAITKEY$
|
||||
|
||||
END FUNCTION
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
/*REXX program finds the common directory path for a list of files. */
|
||||
@. = /*the default for all file lists (null)*/
|
||||
@.1 = '/home/user1/tmp/coverage/test'
|
||||
@.2 = '/home/user1/tmp/covert/operator'
|
||||
@.3 = '/home/user1/tmp/coven/members'
|
||||
L=length(@.1) /*use the length of the first string. */
|
||||
do j=2 while @.j\=='' /*start search with the second string. */
|
||||
_=compare(@.j, @.1) /*use REXX compare BIF for comparison*/
|
||||
if _==0 then iterate /*Strings are equal? Then they're equal*/
|
||||
L=min(L, _) /*find the minimum length equal strings*/
|
||||
end /*j*/
|
||||
@. = /*the default for all file lists (null)*/
|
||||
@.1 = '/home/user1/tmp/coverage/test'
|
||||
@.2 = '/home/user1/tmp/covert/operator'
|
||||
@.3 = '/home/user1/tmp/coven/members'
|
||||
L= length(@.1) /*use the length of the first string. */
|
||||
do j=2 while @.j\=='' /*start search with the second string. */
|
||||
_= compare(@.j, @.1) /*use REXX compare BIF for comparison*/
|
||||
if _==0 then iterate /*Strings are equal? Then con't use min*/
|
||||
L= min(L, _) /*get the minimum length equal strings.*/
|
||||
if right(@.j, 1)=='/' then iterate /*if a directory, then it's OK. */
|
||||
L= lastpos('/', left(@.j, L) ) /*obtain directory name up to here*/
|
||||
end /*j*/
|
||||
|
||||
common=left( @.1, lastpos('/', @.1,L) ) /*determine the shortest DIR string. */
|
||||
if right(common, 1)=='/' then common=left(common, max(0, length(common) - 1) )
|
||||
common= left( @.1, lastpos('/', @.1, L) ) /*determine the shortest DIR string. */
|
||||
if right(common, 1)=='/' then common= left(common, max(0, length(common) - 1) )
|
||||
if common=='' then common= "/" /*if no common directory, assume home. */
|
||||
say 'common directory path: ' common /* [↑] handle trailing / delimiter*/
|
||||
/*stick a fork in it, we're all done. */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn main() {
|
||||
let paths = [
|
||||
Path::new("/home/user1/tmp/coverage/test"),
|
||||
Path::new("/home/user1/tmp/covert/operator"),
|
||||
Path::new("/home/user1/tmp/coven/members"),
|
||||
];
|
||||
match common_path(&paths) {
|
||||
Some(p) => println!("The common path is: {:#?}", p),
|
||||
None => println!("No common paths found"),
|
||||
}
|
||||
}
|
||||
|
||||
fn common_path<I, P>(paths: I) -> Option<PathBuf>
|
||||
where
|
||||
I: IntoIterator<Item = P>,
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let mut iter = paths.into_iter();
|
||||
let mut ret = iter.next()?.as_ref().to_path_buf();
|
||||
for path in iter {
|
||||
if let Some(r) = common(ret, path.as_ref()) {
|
||||
ret = r;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
fn common<A: AsRef<Path>, B: AsRef<Path>>(a: A, b: B) -> Option<PathBuf> {
|
||||
let a = a.as_ref().components();
|
||||
let b = b.as_ref().components();
|
||||
let mut ret = PathBuf::new();
|
||||
let mut found = false;
|
||||
for (one, two) in a.zip(b) {
|
||||
if one == two {
|
||||
ret.push(one);
|
||||
found = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if found {
|
||||
Some(ret)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Public Function CommonDirectoryPath(ParamArray Paths()) As String
|
||||
Dim v As Variant
|
||||
Dim Path() As String, s As String
|
||||
Dim i As Long, j As Long, k As Long
|
||||
Const PATH_SEPARATOR As String = "/"
|
||||
|
||||
For Each v In Paths
|
||||
ReDim Preserve Path(0 To i)
|
||||
Path(i) = v
|
||||
i = i + 1
|
||||
Next v
|
||||
|
||||
k = 1
|
||||
|
||||
Do
|
||||
For i = 0 To UBound(Path)
|
||||
If i Then
|
||||
If InStr(k, Path(i), PATH_SEPARATOR) <> j Then
|
||||
Exit Do
|
||||
ElseIf Left$(Path(i), j) <> Left$(Path(0), j) Then
|
||||
Exit Do
|
||||
End If
|
||||
Else
|
||||
j = InStr(k, Path(i), PATH_SEPARATOR)
|
||||
If j = 0 Then
|
||||
Exit Do
|
||||
End If
|
||||
End If
|
||||
Next i
|
||||
s = Left$(Path(0), j + CLng(k <> 1))
|
||||
k = j + 1
|
||||
Loop
|
||||
CommonDirectoryPath = s
|
||||
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
|
||||
' testing the above function
|
||||
|
||||
Debug.Assert CommonDirectoryPath( _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members") = _
|
||||
"/home/user1/tmp"
|
||||
|
||||
Debug.Assert CommonDirectoryPath( _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/home/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members", _
|
||||
"/home/user1/abc/coven/members") = _
|
||||
"/home/user1"
|
||||
|
||||
Debug.Assert CommonDirectoryPath( _
|
||||
"/home/user1/tmp/coverage/test", _
|
||||
"/hope/user1/tmp/covert/operator", _
|
||||
"/home/user1/tmp/coven/members") = _
|
||||
"/"
|
||||
|
||||
End Sub
|
||||
Loading…
Add table
Add a link
Reference in a new issue