/* For free support for VSIDE, please visit www.vsdsp-forum.com */

// Starting point template for creating VSOS3 libraries and device drivers.
// This will create a <projectname>.DL3 file, which you can copy to 
// your VSRV Developer Board's system disk's SYS subdirectory.

// If init(), main() or fini() are not needed, remove them from the solution.
// There's no need to have any unneeded functions in the library.

#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include <string.h>
#include <kernel.h>

ioresult main(char *parameters) {
  char *p = parameters;
  int nParam;
  int verbose = 1, i;
  int retCode = S_OK;

  nParam = RunProgram("ParamSpl", parameters);

  for (i=0; i<nParam; i++) {
    if (!strcmp(p, "-v")) {
      verbose = 1;
    } else if (!strcmp(p, "+v")) {
      verbose = 0;
    } else if (!strcmp(p, "-h")) {
      printf("Usage: type [-c|+c|-h] [file1 [file2 [...]]]\n"
	     "-v|+v\tVerbose on|off\n"
	     "-h\tShow this help\n");
      goto finally;
    } else {
      FILE *fp = fopen(p, "r");
      u_int16 utf8Bytes = 0;
      u_int32 utf8Res = 0;
      if (!fp) {
	printf("File \"%s\" not found.\n", p);
	retCode = S_ERROR;
      } else {
	u_int16 c;
	fseek(fp, 0, SEEK_END);
	if (verbose) {
	  printf("--------\n");
	  printf("File: %ld bytes, name \"%s\"\n",
		 ftell(fp), fp->Identify(fp, NULL, 0));
	  printf("--------\n");
	}
	fseek(fp, 0, SEEK_SET);
	while ((c = fgetc(fp)) != 0xFFFF) {
	  if ((c & 0xC0) != 0x80) utf8Bytes = 0;
	  
	  if (utf8Bytes) {
	    utf8Res |= (u_int32)(c&0x3f) << (6 * --utf8Bytes);
	    if (!utf8Bytes) {
	      /* UTF8 code finished, now print what we've collected. */
	      if (utf8Res < 0x10000) {
		/* The character fits into 16 bits, so output it directly. */
		putchar((utf8Res > 0xFFFDU) ? 0xFFFDU : utf8Res);
	      } else {
		/* 16 bits is not enough, we need a surrogate pair
		   to present an up to 20-bit Unicode character. */
		if ((utf8Res-=0x10000) >= 0x100000) {
		  /* Illegal code >= 0x110000. */
		  putchar(0xFFFD);
		} else {
		  printf("%c%c",
			 0xD800 | (u_int16)(utf8Res >> 10),
			 0xDC00 | ((u_int16)utf8Res & 0x3FF));
		}
	      }
	    }
	  } else if ((c & 0xC0) == 0xC0) {
      /*
	UTF-8 encodings:
               0, 7 bits  = 00          = 00000000
	    0x7f, 7 bits  = 7f          = 01111111
	    0x80  11 bits = c2 80       = 11000010 10000000
	   0x7ff, 11 bits = df bf       = 11011111 10111111
	   0x800, 16 bits = b0 a0 80    = 11100000 10100000 10000000
	  0xffff, 16 bits = ef bf bf    = 11101111 10111111 10111111
	 0x10000, 21 bits = c0 90 80 80 = 11110000 10010000 10000000 10000000
	0x1fffff, 21 bits = f9 bf bf bf = 11110111 10111111 10111111 10111111
         ...
	0x1ffffffffff, 41 bits = ff bf bf bf bf bf bf bf

	So, if utf8Bytes > 2, then code is at least 0x10000, so overflow
      */
	    utf8Bytes = 1;
	    utf8Res = c;
	    while (((c<<=1) & 0xC0) == 0xC0) {
	      utf8Bytes++;
	    }
	    utf8Res = (utf8Res&(0x3f>>utf8Bytes)) << (6*utf8Bytes);
	    /* UTF8 code not finished, no character to return. */
	  } else {
	    putchar(c);
	  }
	}
	fclose(fp);
      }
    }
    p += strlen(p)+1;
  }

 finally:
  return retCode;
}

