/*  filo -- manipulate a `rolodex'-like database
 *  Copyright (C) 1994 David Deaven, Jennifer Corkill
 *
 *   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.
 *
 * $Id: util.c,v 1.3 1995/10/26 19:53:43 deaven Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dmd/memory.h"
#include "dmd/tools.h"
#include "filo.h"

/* Concatenate string s2 onto s1.  s1 is reallocated and used for the
 * storage.
 */
char *strconcat(char *s1, char *s2)
{
	int len = (s1 ? strlen(s1) : 0) + (s2 ? strlen(s2) : 0) + 1;
	char *s;
	s = myrealloc(s1, len * sizeof(char));
	strcat(s, s2);
	return s;
}
 
/* Copy the contents of file fn, searched for in path, to file f.
 */
void finsert(char *fn, char *path, FILE *f)
{
	int c;
	FILE *fc = fopen_path(path, fn, "r");
	if(fc) {
	  while((c = fgetc(fc)) != EOF) fputc(c, f);
	  fclose(fc);
	} 
	else {
	  fprintf(stderr,
	    "cannot open file `%s' (searched in path \"%s\")\n",
	    fn, path);
	}
}

/* Try to read an environment variable.  If we cannot, use 
 * the given default.  Return a newly-allocated string in any case.
 */
char *tryenv(char *envname, char *defalt)
{
	char *s = NULL;
	if(envname != NULL) s = getenv(envname);
	if(s == NULL) s = defalt;
	return (s == NULL ? s : mystrdup(s));
}

/* Copy an address to the standard output in PostScript
 * using the macros defined in the header file.
 */ 
void addps(FILE *f, char *s)
{
	char *e, save;
	while(*s != '\0') {
	  for(e = s; *e != '\n' && *e != '\0'; ++e);
	  save = *e;
	  *e = '\0';
	  fps_string(f, s);
	  fprintf(f, " cr\n");
	  *e = save;
	  if(*e == '\0') break;
	  s = e + 1;
	}
}

/* Attempt to print the barcode on the envelope.
 * Try to get it from the zipcode in the address.
 */
void barzip(FILE *f, char *s, int x, int y)
{
	int i, j;
	char *lastline, *zip, c;

	if(s[0] == '\0')return; /* stupid case */

	for(i=j=0; s[i+1]!='\0' && s[i+1] != '%'; ++i) if(s[i] == '\n') j = i;
	lastline = s + j + 1;

	for(i=0; lastline[i]!='\0'; ++i)
	{
	  if(isdigit(lastline[i]))
	  {
	    zip = lastline + i;
	    for(i=0; isdigit(zip[i]) || zip[i]=='-'; ++i);
	    c = zip[i]; zip[i] = '\0';
	    fprintf(f, "(%s) EWIDTH .5 mul %d mm add %d mm barcode\n",
	      zip, x, y);
	    zip[i] = c;
	    return;
	  }
	}
}

/* Translate the string to PostScript compatible string,
 * and write the string on the stream f.
 */
void fps_string(FILE *f, char *s)
{
	fputc('(', f);
	while(*s != '\0')
	{
	  switch(*s) {
	    case '~': fputc(' ', f); break;
	    case '\\': break;
	    case '\'': 
	      switch(*(++s)) {
		/* This has to match the header file
		 * font re-encoding definitions.
		 */
		case 'o': fprintf(f, "\\300"); break;
		case 'O': fprintf(f, "\\311"); break;
		case 'u': fprintf(f, "\\321"); break;
		case 'U': fprintf(f, "\\322"); break;
		case 'A': fprintf(f, "\\323"); break;
		case 'a': fprintf(f, "\\324"); break;
		case 'e': fprintf(f, "\\325"); break;
		case 's': fprintf(f, "\\323"); break;
		default: fputc(*s, f); break;
	      }
	      break;
	    default: fputc(*s, f); break;
	  }
	  ++s;
	}
	fputc(')', f);
}

