September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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"
]

View file

@ -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)}`);

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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. */

View file

@ -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
}
}

View file

@ -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