/* * Copyright (c) 1997, 2000, Mark Buser. * Copyright (c) 2003, Danny Backx. * 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 copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the names the authors (see above), nor the names of other * 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. * * $Header: /pack/anoncvs/xinvest/src/util.c,v 1.11 2004/04/30 16:00:18 danny Exp $ */ #include #include #ifdef HAVE_MONETARY_H #include #endif #include #include #include #include #include #ifndef XQUOTE /* Xinvest specific headers */ #include "account.h" #include "calendar.h" #include "fileXi.h" #include "pref.h" #endif #ifdef XQUOTE #include "xquote.h" #else #include "xinvest.h" #endif #include "status.h" #include "util.h" /* ** Program Specific Support */ #ifdef XQUOTE void syntax(int argc, char **argv) { if (argc != 1) fprintf (stderr, "%s: unknown option \"%s\"\n", argv[0], argv[1]); fprintf (stderr, "usage: %s [options ...]\n", argv[0]); fprintf (stderr, "where options include:\n\n" "-help to print this message,\n" "-install to install a private colormap,\n" "-tape tape display with no menu bar,\n" "-restore filename to restore a saved state (a previous session),\n" "or any valid X toolkit option.\n\n"); } #else /* Xinvest */ void syntax(int argc, char **argv) { if (argc != 1) fprintf( stderr, "%s: unknown option \"%s\"\n", argv[0], argv[1]); fprintf( stderr, "usage: %s [options ...]\n", argv[0]); fprintf( stderr, " where options include:\n\n"); fprintf( stderr, " -f filename(s) to load transaction file(s),\n"); fprintf( stderr, " -help to print this message,\n"); fprintf( stderr, " -install to install a private colormap,\n"); fprintf( stderr, " -restore to restore a saved state (a previous session),\n"); fprintf( stderr, " or any valid X toolkit option.\n\n"); } /* Look at an argc/argv pair for the -f filename[s] option. Return argc/argv ** with this option removed. */ void removeFileOption ( int *argc, char **argv ) { int i, j; int start = -1; int end = -1; for (i = 0; i < *argc; i++) { /* ** Find -f option and the next option after it, if any. No filenames ** are allowed to start with '-'. */ if ( argv[i] && strcmp ( "-f", argv[i] ) == 0) { for (start = i, j = i+1; j < *argc; j++) if ( argv[j] && strncmp ("-", argv[j], strlen("-")) == 0) { end = j; break; } } if ( start > 0 ) { /* Found -f option. */ if ( end > 0 ) { /* Option(s) after it, move up to discard -f. */ int newargc = *argc - (end - start); for ( j = end; j < *argc; j++) argv[start++] = argv[j]; if (end < *argc-1) { /* There may be more -f's, look again */ *argc = newargc; removeFileOption (argc, argv); } else { *argc = newargc; } break; } else if ( end == -1 ) { /* No options after it, just decrement argc */ *argc = start; break; } } /* else no -f found, no changes required */ } return; } /* Look at an argc/argv pair for -f filename[s] options. Process the option ** by loading and processing the files. */ void processFileOption ( int argc, char **argv) { int account = 0; /* ** If any options left, they must be data files beginning with -f. ** There may be more than one -f option and each can have zero or more ** filenames [-f filename(s) -f filename(s) ...]. */ argv++; argc--; /* skip executable name */ while (argc) { if ( strcmp ( "-f", *argv) != 0 ) { /* bad option */ sprintf ( errmsg, "Unknown option '%s' ignored,\nexpected '-f filename(s)'.", *argv ); write_status ( errmsg, ERR); argv++; argc--; /* skip -f */ } else { /* -f option, as expected */ argv++; argc--; while ( argc ) { /* any number of filenames */ if (strncmp ( "-", *argv, strlen("-")) == 0) break; /* found option, go back to top */ if ( (account = loadfile( *argv )) ) processAccount( account ); argv++; argc--; } } } if (account) displayAccount( account ); } /* Format date from long format into preference format */ char *utilDateOut (long dateIn) { static char dateStr[20]; char *date = calLtoStr (dateIn); /* in mm/dd/yyyy format */ struct tm dateTm; strptime (date, "%m/%d/%Y", &dateTm); switch (prefGetDate()) { case PREF_DATE_LOC: strftime (dateStr, 20, "%x", &dateTm); break; case PREF_DATE_DMY: strftime (dateStr, 20, "%d/%m/%Y", &dateTm); break; default: case PREF_DATE_MDY: strftime (dateStr, 20, "%m/%d/%Y", &dateTm); break; } return (dateStr); } /* Format monetary double into preference format */ char *utilCurrOut (double currIn, int currency) { static char strval[40], tmp[40]; char *from, *to; char groupc, decc; int leadd, i; int precision = prefGetPrec(); switch (prefGetCurr()) { #ifdef STRFMON case PREF_CURR_LOC: if (currency==UTILCURR) strfmon (strval, 40, "%.2n", currIn); else { char format[10]; sprintf (format, "%%!.%dn", precision); strfmon (strval, 40, format, currIn); } return (strval); #endif case PREF_CURR_DC: groupc = '.'; decc = ','; break; case PREF_CURR_CD: default: groupc = ','; decc = '.'; break; } sprintf (tmp, "%.*f", (currency==UTILCURR)?2:precision, currIn); /* find leading digits */ leadd = strspn (tmp, "0123456789"); to = strval; from = tmp; for (i=0; i < strlen(tmp) && i < 39; i++) { if (i==0 && currency==UTILCURR) { strcpy (to, prefGetCurrChar()); to += strlen (prefGetCurrChar()); } if (leadd) if (leadd--%3 == 0 && i != 0) *to++ = groupc; if (*from == '.' || *from == '.') { *to++ = decc; from++; } else *to++ = *from++; } *to = '\0'; return (strval); } #endif /* Xinvest */ /* ** Host Specific Support */ /* All I want is the lousy max path length, why is this a good thing? */ #ifdef PATH_MAX static int pathmax = PATH_MAX; #else static int pathmax = 0; #endif #define PATH_MAX_GUESS 1024 int path_length () { if (pathmax == 0) { if ((pathmax = pathconf ("/", _PC_PATH_MAX)) < 0) pathmax = PATH_MAX_GUESS; else pathmax++; } return (pathmax); } /* Supplied by Cube-X */ #ifdef NeXT extern char *getwd (char *pathname); char *getcwd ( char *buf, size_t size) { char realBuffer[MAXPATHLEN+1]; int length; if (getwd(realBuffer) == NULL) { errno = EACCES; return NULL; } length = strlen(realBuffer); if (length >= size) { errno = ERANGE; return NULL; } strcpy (buf, realBuffer); return buf; } char *strdup ( const char *src) { char *copy = (char *) malloc(strlen(src)+1); if (copy) strcpy(copy, src); return copy; } #endif /* Unixware needs this. Supplied by Thanh Ma. */ #ifdef NEED_STRCASECMP int strncasecmp(char *s1, char *s2,int n) { register int c1, c2,l=0; while (*s1 && *s2 && ltm_mon, &tm->tm_mday, &tm->tm_year ); else if (strcmp ( fmt, "%m/%d/%Y" ) == 0 ) { sscanf ( buf, "%d/%d/%d", &tm->tm_mon, &tm->tm_mday, &tm->tm_year ); tm->tm_year -= 1900; } else if (strcmp ( fmt, "%m %d %y" ) == 0 ) sscanf ( buf, "%d %d %d", &tm->tm_mon, &tm->tm_mday, &tm->tm_year ); else { sprintf ( err_msg, "internal error: strptime. Unsupported\n" "format: \"%s\". See Reporting Bugs.", fmt); write_status( err_msg, ERR); } tm->tm_mon--; /* Months are from 0-11, mdays from 1-31, years since 1900 */ return NULL; /* completely bogus return value, but I don't use it */ } #endif #ifdef NEED_STRERROR /* Supplied by Benoit Pirenne */ #include extern char *sys_errlist[]; extern int sys_nerr; char *strerror (errnum) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Retrieve the corresponding msg for an given errno .REMARK Only useful on SunOS. Service provided on Solaris! ----------------------------------------------------------------------------*/ int errnum; /* IN: errno value */ { char *p; if ( errnum <= 0 ) p = ""; else if ( errnum <= sys_nerr) p = sys_errlist[errnum]; return p; } #endif