/* @(#)edpic.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:36 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) 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 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++ .MODULE edpic.c .AUTHOR Francois Ochsenbein [ESO] .LANGUAGE C .CATEGORY Edition of integer data .COMMENTS Functions in this module edit numbers using a "picture" or template. \begin{TeX} The picture is a character string specifying how to edit a number. All characters but the following ones are simply copied to the output: \begin{itemize} \item \& ends the picture (starting the next number) \item 0 is replaced either by a digit or by the fill character \item digits in the range 1\dots9 indicate an edition in base $n+1$, \ie 9 for decimal representation, 7 for octal, etc\dots \item X for an hexadecimal edition, performed in uppercase \item $+$ is replaced by the sign, with repetition for floating position. \item $-$ is replaced by a minus sign if the number is negative, or is equivalent to 0 in case of a positive number; the repetition indicates a floating position for the sign. \end{itemize} If neither $+$ nor $-$ character is specified in the picture, the value to be edited is assumed to be {\em unsigned}. Some illustrations: \begin{itemize} \item {\tt "+99 59 59"} (edition of a declination expressed in arc seconds) applied to 86400 results in \fbox{{\tt +24 00 00}} \item {\tt "+++999.9"} applied on the number 256 results in \fbox{{\tt\ \ +025.6"}} \item {\tt "-9.9"} applied on 123 results in {\tt "12.3"}, and applied on -1 results in \fbox{{\tt -0.1}} \item {\tt "77 77 77 77 77 77"} applied on the number -1 results in \fbox{{\tt 03 77 77 77 77 77}}, since the number -1 is in fact $2^{32}-1$. \item {\tt "-XXXX XXXX"} applied on the number -12 results in \fbox{{\tt -0000 000C}} \end{itemize} \end{TeX} To copy the ``picture'' characters to the output, use the \ espace char, i.e. '\+' for +, '\-' for --, etc, and \\ to issue the backslash. .VERSION 1.0 18-Apr-1986: Creation .VERSION 1.1 23-May-1986: Added hexa possibility .VERSION 1.2 03-Mar-1987: Cosmetic modifications. .VERSION 2.0 25-Jan-1988: Integrated for Midas .VERSION 2.1 12-Jun-1989: Sign after digit or dots is taken as `copy char' ----------------------------------------------------------------------------*/ #include /* Required for shareable images... */ #include /* Required for isdigit */ #define ABSOLUTE(x) ((x) < 0 ? (-x) : (x)) /* Absolute*/ #define EOS '\0' /* End Of String */ #define _ERR_CHAR_ '~' /* Character used if edition error occurs */ MID_STATIC unsigned int base = 10; /* Base for the edition of digits */ MID_STATIC unsigned int sign = 0; /* Sign of the number from 0 to 2, used as an index in signs[] */ MID_STATIC int pic_len; /* Where picture stops, used by ed_mpic */ MID_STATIC unsigned char signs[] = { ' ', '-', '+'}; MID_STATIC char fill_char = ' '; MID_RSTATIC char xdigit[] = "0123456789ABCDEF"; /*=========================================================================== * ed_pic *===========================================================================*/ /*++++++ .PURPOSE Edit an integer number according to a picture. .RETURNS The length of the edited number. .REMARKS Digits are replaced with `~' if ``value'' cannot be edited (number too large). The buffer is terminated with the EOS character. ----------*/ int ed_pic(dest, pic, value) char *dest; /* OUT: pointer to destination buffer */ char *pic; /* IN: EOS-terminated picture string */ long int value; /* IN: The integer number to edit */ { unsigned long int n; char *a, *p, *ps; /* ps indicates sign */ unsigned int op; int length; /* Initialisation */ sign = 0 ; base = 10; signs[0] = fill_char; op = 0; ps = (char *)0; /* Look for sign */ for (p=pic; *p; p++) { if (isdigit(*p)) ; else if (*p == '.') ; else if (*p == '+') { if(!ps) sign = 2; continue; } else if (*p == '-') { if(!ps) sign = 1; continue; } else if (*p == 'X') ; else if (*p == '\\') { op++; p++; continue; } else if (*p == '&') break; else continue; if (!ps) ps = p; } if(!ps) ps = p; pic_len = (p--) - pic; length = pic_len - op; a = dest + length; /* Last char of destination string */ *(a--) = EOS; if (sign) /* Look for signed or unsigned number */ { n = ABSOLUTE(value); sign -= (sign-1) ^ (value>=0); /* Leads to 0 or 1 if '-' asked, 1 or 2 if '+' asked */ } else n = (unsigned int) value; /* Edition of digits, from right to left */ for (; p>=pic; p--, a--) { op = 3; /* Default operation */ if ((p>pic) && (*(p-1) == '\\')) { *a = *(p--); continue;} switch(*p) { case '0' : op = (n ? 1 : 0 ); break; case '-' : case '+': if(p '9')||(*p < '0')) break; base = *p - '0' + 1; op = 1; } switch(op) { case 0: *a = fill_char; break; /* Insert fill char */ case 1: *a = xdigit[n%base]; /* Insert a digit */ n /= base; break; case 2: *a = signs[sign]; /* Insert the sign */ sign = 0; break; case 3: *a = *p; /* Copy from picture */ } } if (n | sign) /* Number not completely edited */ { for (p=pic, a=dest; *p; p++, a++) { switch(*p) { case '\\': p++; continue; default : if ((*p > '9')||(*p < '0')) continue; case '+' : case '-' : case 'X': *a = _ERR_CHAR_; } } } return(length); } /*=========================================================================== * ed_pic4 *=========================================================================== /*++++++ .PURPOSE Edit an integer according to a picture, with specified fill character. .RETURNS The length of the edited string. .REMARKS The string is filled with `~' if ``value'' cannot be edited (number too large); .REMARKS The destination string if terminated with an EOS character. ------------*/ int ed_pic4(dest, pic, value, fill) char *dest; /* OUT: pointer to destination string */ char *pic; /* IN: EOS-terminated picture string */ long int value; /* IN: The integer number to edit */ char fill; /* IN: The fill character */ { register int ret; fill_char = fill; ret = ed_pic(dest, pic, value); fill_char = ' '; return(ret); }