
/* ********************************************************************* */
/* *                                                                   * */
/* * Copyright (c) 2007-2010, Dirk Krause                              * */
/* * All rights reserved.                                              * */
/* *                                                                   * */
/* * Redistribution and use in source and binary forms,                * */
/* * with or without modification, are permitted provided              * */
/* * that the following conditions are met:                            * */
/* *                                                                   * */
/* * * Redistributions of source code must retain the above            * */
/* *   copyright notice, this list of conditions and the               * */
/* *   following disclaimer.                                           * */
/* * * Redistributions in binary form must reproduce the above         * */
/* *   opyright notice, this list of conditions and the following      * */
/* *   disclaimer in the documentation and/or other materials          * */
/* *   provided with the distribution.                                 * */
/* * * Neither the name of the Dirk Krause nor the names of            * */
/* *   contributors may be used to endorse or promote                  * */
/* *   products derived from this software without specific            * */
/* *   prior written permission.                                       * */
/* *                                                                   * */
/* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND            * */
/* * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,       * */
/* * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF          * */
/* * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          * */
/* * DISCLAIMED.                                                       * */
/* * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE          * */
/* * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,             * */
/* * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT           * */
/* * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;          * */
/* * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)          * */
/* * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN         * */
/* * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE         * */
/* * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS           * */
/* * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH              * */
/* * DAMAGE.                                                           * */
/* *                                                                   * */
/* ********************************************************************* */

#line 36 "echo2lat.ctr"




/**	@file	echo2lat.c	The echo2lat program.
*/



#include <dk.h>

#include <stdio.h>

#if DK_HAVE_UNISTD_H
#include <unistd.h>
#endif
#if DK_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if DK_HAVE_PROCESS_H
#include <process.h>
#endif
#if DK_HAVE_STRING_H
#include <string.h>
#endif
#if DK_HAVE_STRINGS_H
#include <strings.h>
#endif

#include <dkstr.h>
#include <dkle.h>
#include <dkenc.h>
#include <dksf.h>
#include <dkl2l.h>
#include <dkapp.h>



/**	System configuration directory.
*/
static char sysconf_dir[] = { DK_SYSCONFDIR };



/**	Preference key for shared directory.
*/
static char pk_shdir[] = { "/dir/shared" };


/**	Name of sub directory containing UC to LaTeX encoding tables.
*/
static char str_uc2lat_t[] = { "/uc2lat-t" };



/**	Flag: Input is UTF-8 encoded.
*/
static int have_utf8 = 0;



/**	Check LANG environment variable for UTF-8.
*/
static void check_environment DK_P0()
{
  char *ptr;
  ptr = getenv("LANG");
  if(ptr) {
    ptr = strchr(ptr, '.');
    if(ptr) {
      ptr++;
      if(dkstr_casecmp(ptr, "utf-8") == 0) {
        have_utf8 = 1;
      }
    }
  }
}



/** String: Opening math mode. */
static char str_mm_open[] = { "\\(" };

/** String: Closing math mode. */
static char str_mm_close[] = { "\\)" };



/**	Print one string to output.
	@param	le	LaTeX encoder.
	@param	s	String to print.
	@param	i	Index of the current string in argv.
*/
static
void output_string DK_P3(dk_le_t *,le, char *,s, int,i)
{
  char obuffer[16], *ptr, *res;
  char c; unsigned char uc; unsigned u; dk_udword uw;
  size_t avail, step, u_obuffer;
  int mm, success, cc;
  int error_found;
  if(i > 1) {
    fputc(' ', stdout);
  }
  mm = 0;
  ptr = s;
  error_found = 0;
  if(have_utf8) {
    cc = 1;
    avail = strlen(ptr);
    while(cc) {
      cc = 0;
      if(avail > 0) {
        step = 0;
	cc = dkenc_utf82uc(&uw, (unsigned char *)ptr, avail, &step);
	if(cc) {
	  success = 0;
	  if(dkle_load(le, uw)) {
	    if((res = dkle_get_encoding(le, uw, 0)) != NULL) {
	      if(mm) { fputs(str_mm_close,stdout); } mm = 0;
	      fputs(res, stdout);
	      success = 1;
	    } else {
	      if((res = dkle_get_encoding(le, uw, 0)) != NULL) {
	        if(!mm) { fputs(str_mm_open, stdout); } mm = 1;
		fputs(res, stdout);
		success = 1;
	      }
	    }
	  }
	  if(!success) {
	    if(uw < 256UL) {
	      uc = (unsigned char)uw; c = (char)uc;
	      if(mm) { fputs(str_mm_close,stdout); } mm = 0;
	      if((res = dk_l2l_encoding(c)) != NULL) {
	        fputs(res, stdout);
	      } else {
	        fputc(c, stdout);
	      }
	    } else {
	      /* Convert back to UTF-8, may be handled by inputenc package */
	      u_obuffer = dkenc_uc2utf8(uw,(dk_ubyte *)obuffer,sizeof(obuffer));
	      if(u_obuffer > 0) {
	        obuffer[u_obuffer] = '\0';
		fputs(obuffer, stdout);
	      }
	    }
	  }
	  if(step < avail) {
	    avail = avail - step;
	    while(step--) ptr++;
	  } else {
	    avail = cc = 0;
	  }
	}
      }
      if(error_found) { cc = 0; }
    }
  } else {
    while(*ptr) {
      c = *ptr;
      uc = (unsigned char)c;
      u = (unsigned)uc;
      uw = (dk_udword)u;
      uw = uw & 0x000000FFUL;
      success = 0;
      if(dkle_load(le, uw)) {
        if((res = dkle_get_encoding(le, uw, 0)) != NULL) {
	  if(mm) {
	    fputs(str_mm_close, stdout);
	  } mm = 0;
	  fputs(res, stdout);
	  success = 1;
	} else {
	  if((res = dkle_get_encoding(le, uw, 1)) != NULL) {
	    if(!mm) {
	      fputs(str_mm_open, stdout);
	    } mm = 1;
	    fputs(res, stdout);
	    success = 1;
	  }
	}
      }
      if(!success) {
        if(mm) {
	  fputs(str_mm_close, stdout);
	} mm = 0;
        res = dk_l2l_encoding(c);
	if(res) {
	  fputs(res, stdout);
	} else {
	  fputc(c, stdout);
	}
      }
      ptr++;
    }
    if(mm) {
      fputs(str_mm_close, stdout);
    }
  }
}



/**	The main() function of the echo2lat program.
	@param	argc	Number of command line arguments.
	@param	argv	Command line arguments array.
	@return	0 on success, any other value indicates an error.
*/
#if DK_HAVE_PROTOTYPES
int main(int argc, char *argv[])
#else
int main(argc, argv) int argc; char *argv[];
#endif
{
  int exval = 0;
  dk_app_t *app = NULL;
  dk_le_t *le = NULL;
  static char dirbuffer[1024];
  int i, xargc; char **xargv;
  check_environment();
  app = dkapp_open_ext1(argc, argv, "uc2lat", sysconf_dir, 0, 1);
  if(app) {
    if(dkapp_get_pref(app, pk_shdir, dirbuffer, sizeof(dirbuffer), 0)) {
      if(strlen(dirbuffer) + strlen(str_uc2lat_t) < sizeof(dirbuffer)) {
        strcat(dirbuffer, str_uc2lat_t);
	dksf_correct_fnsep(dirbuffer);
	le = dkle_open(dirbuffer);
	if(le) {
	  xargc = dkapp_get_argc(app); xargv = dkapp_get_argv(app);
	  for(i = 1; i < xargc; i++) {
	    output_string(le, xargv[i], i);
	  }
	  fputc('\n', stdout); fflush(stdout);
	  exval = 1;
	  dkle_close(le);
	} else {
	  /* ##### ERROR */
	}
      }
    }
    dkapp_close(app); app = NULL;
  } else {
    fprintf(stderr, "ERROR: Not enough memory!\n"); fflush(stderr);
  }
  exval = (exval ? 0 : 1);
  exit(exval); return exval;
}



