
 'SYSUTIL.INC

 'Charles Pegge
 '10:51 29/06/2015
 '07:04 14/11/2016
 '13:06 18/04/2018
 '06:49 31/05/2023
 '07:45 11/10/2025

  uses corewin 'minwin
  uses parseutil
  uses timeutil

  typedef char *pchar, *cstring

========
'DIRUTIL
========

 /*
  typedef struct _WIN32_FIND_DATA {
  DWORD    dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD    nFileSizeHigh;
  DWORD    nFileSizeLow;
  DWORD    dwReserved0;
  DWORD    dwReserved1;
  TCHAR    cFileName[MAX_PATH];
  TCHAR    cAlternateFileName[14];
  } WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
*/

'https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx
'selected File Attribute Constants
% FILE_ATTRIBUTE_ARCHIVE          0x20
% FILE_ATTRIBUTE_DEVICE           0x40
% FILE_ATTRIBUTE_DIRECTORY        0x10
% FILE_ATTRIBUTE_HIDDEN           0x2
% FILE_ATTRIBUTE_NORMAL           0x80
% FILE_ATTRIBUTE_READONLY         0x1
% FILE_ATTRIBUTE_SYSTEM           0x4
% FILE_ATTRIBUTE_TEMPORARY        0x100


  function GetFileList(string filter, int*count,optional dirq) as string
  ======================================================================
  '
  '
  macro appendList(s,w,i,  ls,lw) '(string *s,w, int *i)
    int ls=len s
    int lw=len w
    if i+lw>ls
      s+=nuls 1024 '+lw
    end if
    mid s,i+1,w
    i+=lw
  end macro 
  '
  WIN32_FIND_DATA f
  int    a,e,fi
  sys    h
  string flist
  'string cr=chr(13,10)
  '
  h=FindFirstFile filter, @f
  count=0
  if h>0 then
    do
      a=0
      if f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY
        if dirq then a=1
        byte b at @f.cFileName
        if b=46 then  a=0 '.' ' ..'
      else 'NOT A DIRECTORY
        if not dirq then a=1
      end if
      if a then
        count++
        appendlist flist, f.cFileName+cr, fi
      end if
      e=FindNextFile h, @f
      if e=0 then
        e=GetLastError() 'should be 18 when no more files
        exit do
      end if
    end do
    FindClose h
  end if
  return left (flist,fi)
  '
  end function


  function ExtractDirName(string s) as string
  ===========================================
  int i,le
  le=len s
  byte *b=le+strptr s
  for i=le to 1 step -1
     @b--
     if b=47 or b=92
       return left s,i-1
     end if
  next
  return s
  end function


  function ExtractFileName(string s) as string
  ============================================
  int i,le
  le=len s
  byte *b=le+strptr s
  for i=le to 1 step -1
     @b--
     if b=47 or b=92
       return mid s,i+1
     end if
  next
  return s
  end function


  function ExtractDotName(string s) as string
  ===========================================
  int i=len s
  do
    if i<1 then return ""
    if asc(s,i)=46 then return mid(s,i)
    i--
  end do
  end function


  function RtrimDotName(string s) as string
  =========================================
  int i=len s
  do
    if i<1 then return s
    if asc(s,i)=46 then return left(s,i-1)
    i--
  end do
  end function



  ============


  function AppExePath(int n=0) as string
  ======================================
  static byte b[512]
  int i=GetModuleFileName(GetModuleHandle(0), @b, 512)
  while b[i] != 0x5c '92 '\'
    i--
  wend
  if not n then i++ 'include the '\' by default
  b[i]=0
  '= @b 'low level
  char bc at @b
  function=bc
  end function


  function CurDir() as string
  ===========================
  char s[256]
  GetCurrentDirectory 256, s
  return s
  end function


  'process flags:
  %CREATE_NEW_CONSOLE 0x00000010
  %CREATE_NO_WINDOW 0x08000000
  'etc
  '
  function Exec(string c, int wait=0, flags=0) as int
  ===================================================
  STARTUPINFO infs
  PROCESS_INFORMATION infp
  CreateProcess null,c,0,0,0,flags,0,0,@infs,@infp
  if wait
    WaitForMultipleObjects 1,@infp.hthread,1,-1
  end if
  GetExitCodeProcess(infp.hProcess,@function)
  CloseHandle infp.hProcess
  CloseHandle infp.hThread
  end function


  function QuExec(string c,d,f, int wait=0,flags=0) as int
  ========================================================
    return Exec(qu+c+qu+" "+d+" "+qu+f+qu, wait,flags)
  end function
  

  function DOS(string s, int wait=0,flags=0) as int
  =================================================
  string c
  if s then
    c="cmd.exe /c "+s
  else
    c="cmd.exe"
  end if
  return Exec c, wait,flags
  end function


  function CommandLineArgs() as string
  ====================================
  string s,command
  int i=1
  Command = (char) GetCommandLine
  s=GetWord command,i 'step over command filepath\file
  SkipSpace command,i
  return mid Command, i
  end function


  macro CreateArgv
  ================
  sys    argv[64]
  int    argc
  string args = CommandLineArgs
  string arga[64]
  scope
    indexbase 0
    int i=1
    do
      arga[argc]=unquote getword args,i
      if ascb=0 then exit do
      argv[argc] = strptr arga[argc]
      argc++
    end do
  end scope
  end macro

  macro CreateMainCall
  ====================
  ! main cdecl (int argc,char**argv) as int
  main argc, byval @argv
  end macro


