//import win32 ( WIN32_FIND_DATAA, FindFirst ) import win32; import libc; import io.paths; Private stream printWithSprintf: formatString, value [ var buf = Array[CChar, 100]: ; libc.sprintf: &buf[0], (cstring: formatString), value; var n = libc.strlen: &buf[0]; var ptr = Pointer[Byte]: &buf[0]; stream write: ptr, (SizeT: n); ]; Private record FileDirectory[S] ( S path, ); direntSequence('T x) [String?('T)] = [ FileDirectory['T]: x ]; iterator(FileDirectory['T] x) [String?(T)] = [ FileIterator: x.path ]; private: record FileIterator ( win32.HANDLE handle, Bool queued?, win32.WIN32_FIND_DATAA findData, ); private: record FileInfo ( String name, Bool system?, Bool directory?, ); FileIterator: 'T path [String?('T)] = FileIterator self [ self.handle = win32.FindFirstFileA: (cstring: path), &self.findData; self.queued? = true; return self; ]; overload destroy: FileIterator x [ win32.FindClose(x.handle); ]; overload hasNext?(x:FileIterator) [ if: (not: x.queued?) then: [ x.queued? = true; var returnCode = win32.FindNextFileA: x.handle, &x.findData; return (returnCode != 0); ] else: [ return true; ]; ]; flags testFlag: flag = [ (flags bitwiseAnd: flag) == flag ]; next FileIterator x [ if: (not: x.queued?) then: [ hasNext?: x; ] x.queued? = false; return FileInfo: String: (CStringRef: (begin: x.findData.cFileName)), (testFlag: x.findData.dwFileAttributes, win32.FILE_ATTRIBUTE_SYSTEM), (testFlag: x.findData.dwFileAttributes, win32.FILE_ATTRIBUTE_DIRECTORY) ; ]; subtract: Char a, Char b [ return (Int: a)-(Int: b); ]; hexToInt: string [ var number = 0; for: string each: [ char -> if: (char >= '0' and: char <= '9') then: [ number = number * 16 + (char - '0'); ] else: [ if: (char >= 'A' and char <= 'F') then [ number = number * 16 + (char - 'A' + 10); ] else: [ return (false, 0); ]; ]; ]; return (true, number); ]; errorMsg: msg [ println: msg; flush: stdin; var buff = Array[Byte,1]: ; stdin read: (begin: buff), 1; ]; renameFile: a, b [ win32.MoveFileA: (cstring: a), (cstring: b); ]; massren: [ var files = Vector[String]: ; var dir = FileDirectory: "*"; for: dir each: [ fi -> if (and: (not: fi.system?), (not fi.directory?), (fi.name != "massren.exe"), (and fi.name != "massren.txt")) then: [ files push: fi.name; ]; ]; sort: files; if: (not: (io.paths.pathExists?: "massren.txt")) then: [ println: "listing..."; var configFile = File: "massren.txt", CREATE; configFile printWithSprintf: "massren file -- directory hash: %8.0X\n", (hash: files); for: files each: [ f -> printlnTo: configFile, f; ]; println: "done !"; ] else: [ var configFile = File: "massren.txt", READ; var header = readLine: configFile; // print: header; var hashString = slicedFrom: (trimmed: header), (size: "massren file -- directory hash: "); var ok, hash = ...unpack: (hexToInt: hashString); if: (ok and: hash == (prelude.hash: files)) then: [ println: "testing..."; var filesFrom = files; var filesTo = Vector[String]: ; for: files each: [ nameFrom -> push(filesTo, trim(readLine(configFile))); ]; print: filesTo; println: "renaming (1/2)..."; for: (zipped: filesFrom, filesTo) each: [ nameFrom, nameTo -> // println(nameFrom, " -> " ,"massren_temp_"+nameFrom); renameFile(nameFrom, "massren_temp_"+nameFrom); ]; println: "renaming (2/2)..."; for: (zipped: filesFrom, filesTo) each: [ nameFrom, nameTo -> // println: "massren_temp_"+nameFrom, " -> " ,nameTo; renameFile: "massren_temp_"+nameFrom, nameTo; ]; println: "done !"; ] else: [ errorMsg("directory hash mismatch !"); ]; ]; ]; main: [ //stdout printWithSprintf: "massren file -- directory hash: %0.8X\n", 1; massren: ; ];