/* name - gets the fully qualified and quoted name of a file
 * (C) 2000 Kyzer/CSG
 *
 * Compile with VBCC like so:
 *   vc -sc -sd -c fullname.c
 *   PhxLnk SC SD NOSHORTRELOCS fullname.o vlib:amigas.lib to FullName
 */

#include <dos/dosextens.h>
#include <dos/rdargs.h>

#include <exec/execbase.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <exec/types.h>

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <inline/exec_protos.h>
#include <inline/dos_protos.h>

#define TEMPLATE "NOQUOTES/S,NOPATS/S,/A/F" \
		 "\0$VER: FullName 1.0 (21.02.00)"

char *quote(char *src, LONG patterns);

int main(void) {
  struct { LONG noquotes, nopats; STRPTR name; } args;
  struct ExecBase *SysBase;
  struct DosLibrary *DOSBase;
  struct RDArgs *rdargs;
  LONG error = RETURN_FAIL, bufsz = 0;
  APTR buf = NULL;
  BPTR lock;

  SysBase = (*(struct ExecBase **)4UL);
  if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))) {

    args.noquotes = 0;
    args.nopats   = 0;
    args.name     = NULL;
    if ((rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL))) {

      error = RETURN_ERROR;
      if ((lock = Lock(args.name, ACCESS_READ))) {

	/* get full name of file */
	do {
	  FreeVec(buf); bufsz += 256;
	  if (!(buf = AllocVec(bufsz, MEMF_PUBLIC))) break;
	  if ((NameFromLock(lock, (STRPTR)buf, bufsz))) break;
	} while (IoErr() == ERROR_LINE_TOO_LONG);

	/* quote name if neccessary */
	if (buf && !args.noquotes) {

	  char *src = (char *) buf, *dst, *tmp, c;
	  int patterns = !args.nopats, quotes = 0, cnt = 0;

	  /* see if string needs 'quoting' with double quotes */
	  for (tmp = src; c = *tmp++;) {
	    if (c == '"' || c == ' ') {
	      quotes = 1;
	      cnt = 2;
	      break;
	    }
	  }
	
	  /* calculate size of each character in dest - 1, 2 or 3 */
	  for (tmp = src; c = *tmp++;) {
	    switch (c) {
	    case '*':
	      cnt++;
	    case '[': case ']': case '(': case ')': case '|': case '~':
	    case '%': case '#': case '?': case '"': case '\'':
	      cnt++;
	    default:
	      cnt++;
	    }
	  }

	  /* allocate memory for quoted filename */
	  if ((dst = (char *)AllocVec(cnt+1, MEMF_PUBLIC))) {
	    char *out = dst;
	
	    if (quotes) *out++ = '"';
	
	    /* quote characters as we copy */
	    for (tmp = src; c = *tmp++; ) {
	      switch (c) {
	      case '*':
	        if (patterns) *out++ = '\'';
	        if (quotes)   *out++ = '*';
	        *out++ = '*'; break;
	      case '"':
	        if (quotes) *out++ = '*';
	        *out++ = '"'; break;
	
	      case '[': case ']': case '(': case ')': case '|':
	      case '~': case '%': case '#': case '?': case '\'':
	        if (patterns) *out++ = '\'';
	      default:
	        *out++ = c;
	      }
	    }
	    if (quotes) *out++ = '"';
	    *out++ = '\0';
	  }

	  FreeVec((APTR)buf);
	  buf = dst;
	}

	/* now try and print it */
	if (buf) {
	  error = RETURN_OK;
	  VPrintf("%s\n", (APTR)&buf);

	  FreeVec(buf);
	}
	UnLock(lock);
      }
      FreeArgs(rdargs);
    }
    CloseLibrary((struct Library *)DOSBase);
  }

  if (error) PrintFault(IoErr(), args.name);
  return (int) error;
}
