diff interps/c-intercal/src/uncommon.c @ 996:859f9b4339e6

<Gregor> tar xf egobot.tar.xz
author HackBot
date Sun, 09 Dec 2012 19:30:08 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interps/c-intercal/src/uncommon.c	Sun Dec 09 19:30:08 2012 +0000
@@ -0,0 +1,185 @@
+/*
+ * uncommon.c -- functions used by ick, convickt, yuk and compiled programs
+ *
+LICENSE TERMS
+    Copyright (C) 2007 Alex Smith
+
+    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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ick_lose.h>
+#include "uncommon.h"
+
+/* Options that might affect this */
+int ick_printfopens=0;
+
+/*@dependent@*/ /*@null@*/ FILE* ick_debfopen(/*@observer@*/ const char* fname,
+					      /*@observer@*/ const char* mode)
+{
+  FILE* t;
+  if(ick_printfopens) fprintf(stderr,"Trying to open '%s'...\n",fname);
+  t=fopen(fname,mode);
+  if(ick_printfopens && t != NULL) fprintf(stderr,"Success!\n");
+  if(ick_printfopens && t == NULL) fprintf(stderr,"Failed!\n");
+  return t;
+}
+
+/* This function looks for the skeleton and syslib, searching first the
+   path they should be in, then the current directory, then argv[0]'s
+   directory (if one was given). This function avoids possible buffer
+   overflows, instead truncating filenames (and if that manages to find them,
+   I'll be incredibly surprised). It also tries argv[0]/../lib and
+   argv[0]/../include (where they are when running without installing). */
+/*@dependent@*/ /*@null@*/ FILE* ick_findandfopen(/*@observer@*/ const char* file,
+						  /*@observer@*/ const char* guessdir,
+						  /*@observer@*/ const char* mode,
+						  /*@observer@*/ const char* argv0)
+{
+  static char buf2[BUFSIZ];
+  /*@observer@*/ static const char *fileiter;
+  size_t i = 0, j;
+  FILE* ret;
+  while(*guessdir != '\0' && i<BUFSIZ-2) buf2[i++] = *guessdir++;
+  buf2[i++] = '/';
+  fileiter = file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i] = '\0';
+  ret = ick_debfopen(buf2,mode); /* where it ought to be */
+  if(ret) return ret;
+  ret = ick_debfopen(file,mode); /* current dir */
+  if(ret) return ret;
+  if(!strchr(argv0,'/')&&
+     !strchr(argv0,'\\')) return NULL; /* argv[0] has no dir specified */
+  i = j = 0;
+  while(*argv0 != '\0' && i<BUFSIZ-2)
+  {
+    buf2[i++] = *argv0++;
+    if(*argv0=='/') j = i;
+    if(*argv0=='\\') j = i;
+  }
+  i = j + 1;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i] = '\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]'s dir */
+  if(ret) return ret;
+  i = j + 1;
+  fileiter="../lib/"; /* correct for POSIX and DJGPP */
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i]='\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]/../lib/ */
+  if(ret) return ret;
+  i = j + 1;
+  fileiter="../include/"; /* correct for POSIX and DJGPP */
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i]='\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]/../include/ */
+  if(ret) return ret;
+  return NULL; /* just return 0 if even this failed */
+}
+
+/* AIS: The same, looking for an executable */
+/*@observer@*/ /*@null@*/ const char* ick_findandtestopen(/*@observer@*/ const char* file,
+						          /*@observer@*/ const char* guessdir,
+						          /*@observer@*/ const char* mode,
+						          /*@observer@*/ const char* argv0)
+{
+  static char buf2[BUFSIZ];
+  /*@observer@*/ static const char *fileiter;
+  size_t i = 0, j;
+  FILE* ret;
+  while(*guessdir != '\0' && i<BUFSIZ-2) buf2[i++] = *guessdir++;
+  buf2[i++] = '/';
+  fileiter = file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i] = '\0';
+  ret = ick_debfopen(buf2,mode); /* where it ought to be */
+  if(ret) {(void) fclose(ret); return buf2;}
+  ret = ick_debfopen(file,mode); /* current dir */
+  if(ret) {(void) fclose(ret); return file;}
+  if(!strchr(argv0,'/')&&
+     !strchr(argv0,'\\')) return 0; /* argv[0] has no dir specified */
+  i = j = 0;
+  while(*argv0 != '\0' && i<BUFSIZ-2)
+  {
+    buf2[i++] = *argv0++;
+    if(*argv0=='/') j = i;
+    if(*argv0=='\\') j = i;
+  }
+  i = j + 1;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i] = '\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]'s dir */
+  if(ret) {(void) fclose(ret); return buf2;}
+  i = j + 1;
+  fileiter="../lib/"; /* correct for POSIX and DJGPP */
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i]='\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]/../lib/ */
+  if(ret) {(void) fclose(ret); return buf2;}
+    i = j + 1;
+  fileiter="../include/"; /* correct for POSIX and DJGPP */
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  fileiter=file;
+  while(*fileiter != '\0' && i<BUFSIZ-1) buf2[i++] = *fileiter++;
+  buf2[i]='\0';
+  ret = ick_debfopen(buf2,mode); /* argv[0]/../include/ */
+  if(ret) {(void) fclose(ret); return buf2;}
+  return 0; /* just return 0 if even this failed */
+}
+
+/* AIS: The same thing, but with freopen */
+/*@dependent@*/ /*@null@*/ FILE* ick_findandfreopen(/*@observer@*/ const char* file,
+						    /*@observer@*/ const char* guessdir,
+						    /*@observer@*/ const char* mode,
+						    /*@observer@*/ const char* argv0,
+						    FILE* over)
+{
+  const char* s=ick_findandtestopen(file,guessdir,mode,argv0);
+  if(s != NULL)
+    return freopen(s,mode,over);
+  else
+    return NULL;
+}
+
+/**
+ * Invoke snprintf(), if supported. Otherwise invoke sprintf() and abort
+ * if we did overflow.
+ */
+int ick_snprintf_or_die(/*@out@*/ char *str, size_t size, /*@observer@*/ const char *format, ...)
+{
+  va_list ap;
+  int retval;
+  va_start(ap, format);
+#ifdef HAVE_VSNPRINTF
+  retval = vsnprintf(str, size, format, ap);
+#else
+  retval = vsprintf(str, format, ap);
+  if (retval >= size)
+    ick_lose(IE553, 0, (const char*)NULL);
+#endif
+  va_end(ap);
+  return retval;
+}