/*{{{  #includes*/
#ifdef CONFIG_H
#   include "config.h"
#endif

#ifdef VARARGS
#  include <varargs.h>
#else
#  include <stdarg.h>
#endif
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#include <local/bool.h>

#define GETMSG_C
#define I_MESSAGES_C

#include "origami.h"
/*}}}  */

/*{{{  variable declarations*/
public int msg_file;
public msgtyp last_message=0;
/*}}}  */

/*{{{  i_to_a*/
public char *i_to_a(int x)
{
#  define NBSIZE ((sizeof(int)<<2)+1)
  static char number[NBSIZE];
  char *s=number+NBSIZE-1;
  bool neg;

  if (neg=(x<0)) x= -x;
  *s=0;
  do
   { *(--s)="0123456789"[x%10]; }
  while ((x/=10)>0);
  if (neg) *(--s)='-';
  return(s);
}
/*}}}  */
/*{{{  get and format a message*/
#ifdef VARARGS
   public unsigned char *get_msg(n,va_alist) msgtyp n; va_dcl
#else
   public unsigned char *get_msg(msgtyp n, ... )
#endif
{
  /*{{{  variable declarations*/
  va_list ap;
  static unsigned char s[LINELEN+1];
  static unsigned char r[MSG_LENGTH+2]="";
  unsigned char *x,*y=s,*z;
  /*}}}  */

#  ifdef VARARGS
     va_start(ap);
#  else
     va_start(ap,n);
#  endif
  if (n!=M_BASE_FORMAT)
     if (n==last_message)
        x=r+1;
     else
      /*{{{  get message from file*/
        if (   (lseek(msg_file,(off_t)((n-1)*(MSG_LENGTH+MSG_ADDITIONAL)),SEEK_SET)==-1)
            || (read(msg_file,(char *)r+1,MSG_LENGTH)==-1)
            || !r[1]
           )
           x=M_UN_MES;
        else
         { x=r+MSG_LENGTH;
           while (*--x==' ');
           *(x+1)='\0';
           x=r+1;
           if (!*x) x=tspace+2;
         }
      /*}}}  */
  else
     x=(unsigned char *)BASENAMEF;
  last_message=n;
  while (*x)
     switch (*x)
      {
        /*{{{  % only %s and %d implemented*/
        case '%':
         { if (*++x=='s')
              z=va_arg(ap,unsigned char*);
           else if (*x=='d')
              z=(unsigned char*)i_to_a(va_arg(ap,int));
           else
              z=empty_text;
           while (*z) *y++ = *z++;
           x++;
           break;
         }
        /*}}}  */
        /*{{{  \ - only \n,\\ implemented*/
        case '\\':
         { if (*++x=='n')
              *y++='\n';
           else if (*x=='\\')
              *y++='\\';
           x++;
           break;
         }
        /*}}}  */
        /*{{{  default*/
        default: *y++ = *x++;
        /*}}}  */
      }
  *y='\0';
  va_end(ap);
  return s;
}
/*}}}  */
