#line 1 "/build/ecl/src/ecl-26.3.27/src/c/file.d"
/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* vim: set filetype=c tabstop=2 shiftwidth=2 expandtab: */

/*
 * file.d - file interface
 *
 * Copyright (c) 1984 Taiichi Yuasa and Masami Hagiya
 * Copyright (c) 1990 Giuseppe Attardi
 * Copyright (c) 2001 Juan Jose Garcia Ripoll
 *
 * See file 'LICENSE' for the copyright details.
 *
 */

/* -- imports --------------------------------------------------------------- */

#include <ecl/ecl.h>
#include <ecl/internal.h>

/* -- File opening and closing ---------------------------------------------- */

cl_fixnum
ecl_normalize_stream_element_type(cl_object element_type)
{
  cl_fixnum sign = 0;
  cl_index size;
  if (element_type == ECL_SYM("SIGNED-BYTE",764) || element_type == ECL_SYM("EXT::INTEGER8",1373)) {
    return -8;
  } else if (element_type == ECL_SYM("UNSIGNED-BYTE",889) || element_type == ECL_SYM("EXT::BYTE8",1368)) {
    return 8;
  }
#ifdef ecl_uint16_t
  else if (element_type == ECL_SYM("EXT::INTEGER16",1374)) {
    return -16;
  } else if (element_type == ECL_SYM("EXT::BYTE16",1369)) {
    return 16;
  }
#endif
#ifdef ecl_uint32_t
  else if (element_type == ECL_SYM("EXT::INTEGER32",1375)) {
    return -32;
  } else if (element_type == ECL_SYM("EXT::BYTE32",1370)) {
    return 32;
  }
#endif
#ifdef ecl_uint64_t
  else if (element_type == ECL_SYM("EXT::INTEGER64",1376)) {
    return -64;
  } else if (element_type == ECL_SYM("EXT::BYTE64",1371)) {
    return 64;
  }
#endif
  else if (element_type == ECL_SYM(":DEFAULT",1246)) {
    return 0;
  } else if (element_type == ECL_SYM("BASE-CHAR",122) || element_type == ECL_SYM("CHARACTER",224)) {
    return 0;
  } else if (_ecl_funcall3(ECL_SYM("SUBTYPEP",840), element_type, ECL_SYM("CHARACTER",224)) != ECL_NIL) {
    return 0;
  } else if (_ecl_funcall3(ECL_SYM("SUBTYPEP",840), element_type, ECL_SYM("UNSIGNED-BYTE",889)) != ECL_NIL) {
    sign = +1;
  } else if (_ecl_funcall3(ECL_SYM("SUBTYPEP",840), element_type, ECL_SYM("SIGNED-BYTE",764)) != ECL_NIL) {
    sign = -1;
  } else {
    FEerror("Not a valid stream element type: ~A", 1, element_type);
  }
  if (CONSP(element_type)) {
    if (CAR(element_type) == ECL_SYM("UNSIGNED-BYTE",889))
      return ecl_to_size(cl_cadr(element_type));
    if (CAR(element_type) == ECL_SYM("SIGNED-BYTE",764))
      return -ecl_to_size(cl_cadr(element_type));
  }
  for (size = 8; 1; size++) {
    cl_object type;
    type = cl_list(2, sign>0? ECL_SYM("UNSIGNED-BYTE",889) : ECL_SYM("SIGNED-BYTE",764),
                   ecl_make_fixnum(size));
    if (_ecl_funcall3(ECL_SYM("SUBTYPEP",840), element_type, type) != ECL_NIL) {
      return size * sign;
    }
  }
  FEerror("Not a valid stream element type: ~A", 1, element_type);
}

#line 92
cl_object cl_open(cl_narg narg, cl_object filename, ...)
{
#line 92

  enum ecl_smmode smm;
  int flags = 0;
  cl_fixnum byte_size;
#line 97
#if defined(__clang__) || defined(__GNUC__)
	__attribute__((unused)) const cl_env_ptr the_env = ecl_process_env();
#else
	const cl_env_ptr the_env = ecl_process_env();
#endif
#line 97
	static cl_object KEYS[8] = {(cl_object)(cl_symbols+1249), (cl_object)(cl_symbols+1255), (cl_object)(cl_symbols+1279), (cl_object)(cl_symbols+1277), (cl_object)(cl_symbols+1267), (cl_object)(cl_symbols+1362), (cl_object)(cl_symbols+1237), (cl_object)(cl_symbols+1314)};
	cl_object direction;
	cl_object element_type;
	cl_object if_exists;
	bool iesp;
	cl_object if_does_not_exist;
	bool idnesp;
	cl_object external_format;
	cl_object cstream;
	cl_object close_on_exec;
	cl_object nonblock;
#line 97
	cl_object strm;
#line 97
	cl_object KEY_VARS[16];
#line 97
	ecl_va_list ARGS;
	ecl_va_start(ARGS, filename, narg, 1);
#line 97
	if (ecl_unlikely(narg < 1)) FEwrong_num_arguments(ecl_make_fixnum(613));
#line 97
	cl_parse_key(ARGS, 8, KEYS, KEY_VARS, NULL, 0);
#line 97
	if (KEY_VARS[8]==ECL_NIL) {
#line 97
	  direction = ECL_SYM(":INPUT",1289);
	} else {
#line 97
	  direction = KEY_VARS[0];
	}
#line 97
	if (KEY_VARS[9]==ECL_NIL) {
#line 97
	  element_type = ECL_SYM("CHARACTER",224);
	} else {
#line 97
	  element_type = KEY_VARS[1];
	}
#line 97
	if (KEY_VARS[10]==ECL_NIL) {
#line 97
	  if_exists = ECL_NIL;
#line 97
	  iesp = FALSE;
	} else {
#line 97
	  iesp = TRUE;
#line 97
	  if_exists = KEY_VARS[2];
	}
#line 97
	if (KEY_VARS[11]==ECL_NIL) {
#line 97
	  if_does_not_exist = ECL_NIL;
#line 97
	  idnesp = FALSE;
	} else {
#line 97
	  idnesp = TRUE;
#line 97
	  if_does_not_exist = KEY_VARS[3];
	}
#line 97
	if (KEY_VARS[12]==ECL_NIL) {
#line 97
	  external_format = ECL_SYM(":DEFAULT",1246);
	} else {
#line 97
	  external_format = KEY_VARS[4];
	}
#line 97
	if (KEY_VARS[13]==ECL_NIL) {
#line 97
	  cstream = ECL_T;
	} else {
#line 97
	  cstream = KEY_VARS[5];
	}
#line 97
	if (KEY_VARS[14]==ECL_NIL) {
#line 97
	  close_on_exec = ECL_T;
	} else {
#line 97
	  close_on_exec = KEY_VARS[6];
	}
#line 97
	if (KEY_VARS[15]==ECL_NIL) {
#line 97
	  nonblock = ECL_NIL;
	} else {
#line 97
	  nonblock = KEY_VARS[7];
	}
#line 97
	strm = ECL_NIL;
#line 97
  /* INV: ecl_open_stream() checks types */
  if (direction == ECL_SYM(":INPUT",1289)) {
    smm = ecl_smm_input;
    if (!idnesp)
      if_does_not_exist = ECL_SYM(":ERROR",1260);
  } else if (direction == ECL_SYM(":OUTPUT",1319)) {
    smm = ecl_smm_output;
    if (!iesp)
      if_exists = ECL_SYM(":NEW-VERSION",1311);
    if (!idnesp) {
      if (if_exists == ECL_SYM(":OVERWRITE",1320) ||
          if_exists == ECL_SYM(":APPEND",1228))
        if_does_not_exist = ECL_SYM(":ERROR",1260);
      else
        if_does_not_exist = ECL_SYM(":CREATE",1244);
    }
  } else if (direction == ECL_SYM(":IO",1295)) {
    smm = ecl_smm_io;
    if (!iesp)
      if_exists = ECL_SYM(":NEW-VERSION",1311);
    if (!idnesp) {
      if (if_exists == ECL_SYM(":OVERWRITE",1320) ||
          if_exists == ECL_SYM(":APPEND",1228))
        if_does_not_exist = ECL_SYM(":ERROR",1260);
      else
        if_does_not_exist = ECL_SYM(":CREATE",1244);
    }
  } else if (direction == ECL_SYM(":PROBE",1330)) {
    smm = ecl_smm_probe;
    if (!idnesp)
      if_does_not_exist = ECL_NIL;
  } else {
    FEerror("~S is an illegal DIRECTION for OPEN.",
            1, direction);
  }
  byte_size = ecl_normalize_stream_element_type(element_type);
  if (byte_size != 0) {
    external_format = ECL_NIL;
  }
  if (!Null(cstream)) {
    flags |= ECL_STREAM_C_STREAM;
  }
  if (!Null(close_on_exec)) {
    flags |= ECL_STREAM_CLOSE_ON_EXEC;
  }
  if (!Null(nonblock)) {
    flags |= ECL_STREAM_NONBLOCK;
  }
  strm = ecl_open_stream(filename, smm, if_exists, if_does_not_exist,
                         byte_size, flags, external_format);
  {
#line 147
	#line 147
	cl_object __value0 = strm;
#line 147
	the_env->nvalues = 1;
#line 147
	the_env->values[0] = __value0;
#line 147
	ecl_va_end(ARGS);
#line 147
	return __value0;
#line 147
}
;
}

#line 150
cl_object cl_close(cl_narg narg, cl_object strm, ...)
{
#line 150

#line 152
#if defined(__clang__) || defined(__GNUC__)
	__attribute__((unused)) const cl_env_ptr the_env = ecl_process_env();
#else
	const cl_env_ptr the_env = ecl_process_env();
#endif
#line 152
	static cl_object KEYS[1] = {(cl_object)(cl_symbols+1225)};
	cl_object abort;
#line 152
	cl_object KEY_VARS[2];
#line 152
	ecl_va_list ARGS;
	ecl_va_start(ARGS, strm, narg, 1);
#line 152
	if (ecl_unlikely(narg < 1)) FEwrong_num_arguments(ecl_make_fixnum(230));
#line 152
	cl_parse_key(ARGS, 1, KEYS, KEY_VARS, NULL, 0);
#line 152
	if (KEY_VARS[1]==ECL_NIL) {
#line 152
	  abort = ECL_NIL;
	} else {
#line 152
	  abort = KEY_VARS[0];
	}
#line 152
  {
#line 152
	#line 152
	cl_object __value0 = ecl_stream_dispatch_table(strm)->close(strm);
#line 152
	the_env->nvalues = 1;
#line 152
	the_env->values[0] = __value0;
#line 152
	ecl_va_end(ARGS);
#line 152
	return __value0;
#line 152
}
;
}
