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

/// \file liblist.c Print out a list of loaded libraries and free mem to stdout
/// \author Panu-Kristian Poiksalo, VLSI Solution Oy


#include <vo_stdio.h>
#include <volink.h>
#include <apploader.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <kernel.h>

u_int16 LibNameCompare(register u_int16 *lib, register const char *name) {
  char *s;
  lib += *lib + 6;
  s = (char *)(lib + *lib * 2 + 2);

  while (1) {
    if (!(*name)) return 1;
    if (!(*s)) return 1;
    if (toupper(*s) != toupper(*name)) return 0;
    s++; name++;
  }
}

void *FindLib(register const char *name) {
  u_int16 i;
  void **ll = loadedLib;
  for (i=0; i<loadedLibs; i++) {
    if (LibNameCompare(*ll, name)) return *ll;
    ll++;
  }
  return NULL;
}



ioresult main(char *parameters) {
  u_int16 i;
  volatile u_int16 *lib;

  lib = FindLib(&parameters[1]);
  switch (parameters[0]) {
  case '?': {
    if (!lib) {
      break;
    }
    printf("Lib %s is at %p.\n", parameters+1, lib);
    return S_OK;
  }

  case '-': {
    if (!lib) {
      return S_ERROR;
    }
    lib[1] = 1;
    DropLibrary((void*)lib);
    return S_OK;
  }

  case '+':
  case '!': {
    char *program = parameters+1;
    char *params = strchr(program, ' ');
    while (*params == ' ') {
      *params++ = '\0';
    }
    lib = LoadLibraryP(program, params);
    if (lib) {
      if (parameters[0] == '+' && lib[2+ENTRY_MAIN]) {
	// Run main function if it exists and not loaded with '!'
	return RunLoadedFunction(lib, ENTRY_MAIN, (int)params);
      } else {
	// If main run with '!' or main function doesn't exist, that's ok
    	return S_OK;
      }
    }
    return S_ERROR;
  }

  default: {
    printf("Usage: DRIVER {+|!|-|?}libname\n");
    return S_ERROR;
  }
  }

  printf("Lib %s not found.\n", parameters+1);
  return S_ERROR;
}
