/*

Freely Distributable C30 Simulator Package

Copyright (c) 1996-1998 The University of Texas
All Rights Reserved.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
The GNU Public License is available in the file LICENSE, or you
can write to the Free Software Foundation, Inc., 59 Temple Place -
Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
World Wide Web at http://www.fsf.org.

Authors: Chi Duong and Brian Evans
Version: @(#)asupport.cc	1.5	01/19/98

Department of Electrical and Computer Engineering
The University of Texas, Austin, TX 78712-1084

*/

/*
This file mimics the non-standard Borland C++ routines
strlwr, strupr, and fcloseall.
*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "asupport.h"

#define MAX_OPEN_FILES  64

static FILE* OpenAssemblerFilesArray[MAX_OPEN_FILES];
static int OpenAssemblerFilesMaxIndex = 0;
 
/*
Convert a string to lower case.
*/
void strlwr(unsigned char *str) {
  while (*str) {
    if (isupper(*str)) *str = tolower(*str);
    str++;
  }
}

/*
Convert a string to upper case.
*/
void strupr(unsigned char *str) {
  while (*str) {
    if (islower(*str)) *str = toupper(*str);
    str++;
  }
}

/*
Call this funcion every time we need to open a file using fopen()
*/
void C30SimRegisterAssemblerFile(FILE* openedFile) {
  if ((openedFile != 0) && (OpenAssemblerFilesMaxIndex < MAX_OPEN_FILES)) {
    OpenAssemblerFilesArray[OpenAssemblerFilesMaxIndex++] = openedFile;
  }
}
 
/*
Call this function every time we need to close a file using fclose().
*/
void C30SimUnregisterAssemblerFile(FILE* closedFile) {
  int count;
  for (count = 0; count < OpenAssemblerFilesMaxIndex; count++) {
    if (OpenAssemblerFilesArray[count] == closedFile) break;
  }
  if (count < OpenAssemblerFilesMaxIndex) {
    count++;
    while (count < OpenAssemblerFilesMaxIndex) {
      OpenAssemblerFilesArray[count - 1] = OpenAssemblerFilesArray[count];
      count++;
    }
    OpenAssemblerFilesMaxIndex--;
  }
}

/*
Call this function to close all opened files.
Use this function in place of the fcloseall function.
*/
void C30SimCloseAllAssemblerFiles() {
    int i;
    for (i = OpenAssemblerFilesMaxIndex - 1; i >= 0; i--) {
      fclose(OpenAssemblerFilesArray[i]);
      OpenAssemblerFilesArray[i] = 0;
    }
    OpenAssemblerFilesMaxIndex = 0;
}

/*
Check for a safe path name for the Web-based version.
We don't allow users to write to directories above the
one they are currently in.
*/
int C30SimSafePathName(const char* pathname) {
  int safeFlag = 1;
  if ( pathname == 0 ) safeFlag = 0;
  else if ( *pathname == 0 ) safeFlag = 0;
  else if ( *pathname == '/' ) safeFlag = 0;
  else if ( pathname[1] == ':' ) safeFlag = 0;
  else if ( strstr(pathname, "..") ) safeFlag = 0;
  else if ( strchr(pathname, '~') ) safeFlag = 0;
  return safeFlag;
}
