"Fossies" - the Fresh Open Source Software Archive

Member "jpilot-2_0_1/print.c" (3 Apr 2021, 40224 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "print.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.2_vs_2_0_1.

    1 /*******************************************************************************
    2  * print.c
    3  * A module of J-Pilot http://jpilot.org
    4  *
    5  * Copyright (C) 2000-2014 by Judd Montgomery
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; version 2 of the License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  ******************************************************************************/
   20 
   21 /********************************* Includes ***********************************/
   22 #include "config.h"
   23 #include <stdlib.h>
   24 #include <stdio.h>
   25 #include <string.h>
   26 #include <time.h>
   27 #include <ctype.h>
   28 
   29 #include "print.h"
   30 #include "print_headers.h"
   31 #include "print_logo.h"
   32 #include "datebook.h"
   33 #include "calendar.h"
   34 #include "address.h"
   35 #include "todo.h"
   36 #include "sync.h"
   37 #include "prefs.h"
   38 #include "log.h"
   39 #include "i18n.h"
   40 #ifdef HAVE_LOCALE_H
   41 #  include <locale.h>
   42 #endif
   43 
   44 /********************************* Constants **********************************/
   45 #ifdef JPILOT_PRINTABLE
   46 #  define FLAG_CHAR 'A'
   47 #  define Q_FLAG_CHAR "A"
   48 #else
   49 #  define FLAG_CHAR 010
   50 #  define Q_FLAG_CHAR "\\010"
   51 #endif
   52 
   53 /******************************* Global vars **********************************/
   54 static FILE *out;
   55 static int first_hour, first_min, last_hour, last_min;
   56 extern int datebk_category;
   57 
   58 static const char *PaperSizes[] = { 
   59    "Letter", "Legal", "Statement", "Tabloid", "Ledger", "Folio", "Quarto",
   60    "7x9", "9x11", "9x12", "10x13", "10x14", "Executive", 
   61    "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10",
   62    "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", 
   63    "ISOB0", "ISOB1", "ISOB2", "ISOB3", "ISOB4", "ISOB5", "ISOB6", "ISOB7", 
   64    "ISOB8", "ISOB9", "ISOB10", 
   65    "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "DL", "Filo"
   66 };
   67 
   68 /****************************** Prototypes ************************************/
   69 static int fill_in(struct tm *date, CalendarEventList *a_list);
   70 static void ps_strncat(char *dest, const char *src, int n);
   71 
   72 /****************************** Main Code *************************************/
   73 static FILE *print_open(void)
   74 {
   75    const char *command;
   76 
   77    get_pref(PREF_PRINT_COMMAND, NULL, &command);
   78    if (command) {
   79       return popen(command, "w");
   80    } else {
   81       return NULL;
   82    }
   83 }
   84 
   85 static void print_close(FILE *f)
   86 {
   87    pclose(f);
   88 }
   89 
   90 static int courier_12(void)
   91 {
   92    /* fprintf(out, "/Courier 12 selectfont\n"); */
   93    fprintf(out, "%cC12\n", FLAG_CHAR);
   94    return EXIT_SUCCESS;
   95 }
   96 
   97 static int courier_bold_12(void)
   98 {
   99    /* fprintf(out, "/Courier-Bold 12 selectfont\n"); */
  100    fprintf(out, "%cCB12\n", FLAG_CHAR);
  101    return EXIT_SUCCESS;
  102 }
  103 
  104 static int clip_to_box(float x1, float y1, float x2, float y2)
  105 {
  106    fprintf(out, "%g inch %g inch %g inch %g inch rectclip\n",
  107                  x1,     y1,     x2-x1,  y2-y1);
  108    return EXIT_SUCCESS;
  109 }
  110 
  111 static int puttext(float x, float y, const char *text)
  112 {
  113    int len;
  114    char *buf;
  115 
  116    len = strlen(text);
  117    buf = malloc(2 * len + 1);
  118    memset(buf, 0, 2 * len + 1);
  119    ps_strncat(buf, text, 2 * len);
  120    fprintf(out, "%g inch %g inch moveto (%s) show\n", x, y, buf);
  121    free(buf);
  122    return EXIT_SUCCESS;
  123 }
  124 
  125 static int header(void)
  126 {
  127    time_t ltime;
  128 
  129    time(&ltime);
  130    fprintf(out,
  131            "%%!PS-Adobe-2.0\n"
  132            "%%%%Creator: J-Pilot\n"
  133            "%%%%CreationDate: %s"
  134            "%%%%DocumentData: Clean7Bit\n"
  135            "%%%%Orientation: Portrait\n"
  136            "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
  137            "%%%%Magnification: 1.0000\n"
  138            "%%%%Pages: 1\n"
  139            "%%%%EndComments\n"
  140            "%%%%BeginProlog\n"
  141            ,ctime(&ltime));
  142    fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[PAPER_Letter]);
  143    print_common_prolog(out);
  144    fprintf(out,
  145            "%%%%EndProlog\n"
  146            "%%%%BeginSetup\n");
  147    print_common_setup(out);
  148    fprintf(out, "595 612 div 842 792 div Min dup scale %% HACK!!!! (CMB)\n");
  149            /* This hack pre-scales to compensate for the standard scaling
  150               mechanism below, to avoid me having to redo the layout of
  151               the dayview for the A4 standard size page. */
  152    fprintf(out,
  153            "%%%%EndSetup\n"
  154            "%%%%Page: 1 1\n\n");
  155 
  156    return EXIT_SUCCESS;
  157 }
  158 
  159 static int print_dayview(struct tm *date, CalendarEventList *ce_list)
  160 {
  161    char str[80];
  162    char datef[80];
  163    time_t ltime;
  164    struct tm *now;
  165    const char *svalue;
  166 
  167 #ifdef HAVE_LOCALE_H
  168    char *current_locale;
  169    current_locale = setlocale(LC_NUMERIC,"C");
  170 #endif
  171 
  172    header();
  173    /* Draw the 2 gray columns and header block */
  174    print_day_header(out);
  175 
  176    /* Put the month name up */
  177    fprintf(out, "/Times-Bold-ISOLatin1 findfont 20 scalefont setfont\n"
  178                 "newpath 0 setgray\n");
  179    get_pref(PREF_LONGDATE, NULL, &svalue);
  180    strftime(str, sizeof(str), _(svalue), date);
  181    puttext(0.5, 10.25, str);
  182 
  183    /* Put the weekday name up */
  184    fprintf(out, "/Times-Roman-ISOLatin1 findfont 15 scalefont setfont\n");
  185    strftime(str, sizeof(str), "%A", date);
  186    puttext(0.5, 10, str);
  187 
  188    /* Put the time of printing up */
  189    fprintf(out, "newpath\n"
  190                 "/Times-Roman-ISOLatin1 findfont 10 scalefont setfont\n");
  191 
  192    time(&ltime);
  193    now = localtime(&ltime);
  194    get_pref(PREF_SHORTDATE, NULL, &svalue);
  195    g_snprintf(datef, sizeof(datef), "%s %s", "Printed on: ", svalue);
  196    strftime(str, sizeof(str), datef, now);
  197    puttext(0.5, 0.9, str);
  198    puttext(7.5, 0.9, "J-Pilot");
  199    fprintf(out, "stroke\n");
  200 
  201    print_logo(out, 40, 90, 0.35);
  202 
  203    /* Put the appointments on the dayview calendar */
  204    fill_in(date, ce_list);
  205 
  206    fprintf(out, "showpage\n");
  207    fprintf(out, "%%%%EOF\n");
  208 
  209 #ifdef HAVE_LOCALE_H
  210    setlocale(LC_ALL, current_locale);
  211 #endif
  212 
  213    return EXIT_SUCCESS;
  214 }
  215 
  216 static int fill_in(struct tm *date, CalendarEventList *ce_list)
  217 {
  218    CalendarEventList *temp_cel;
  219    int i;
  220    int hours[24];
  221    int defaults1=0, defaults2=0;
  222    int hour24;
  223    int am;
  224    float top_y=9.40;
  225    float default_y=3.40;
  226    float indent1=1.25;
  227    float indent2=5.00;
  228    float step=0.12; /* This is the space between lines */
  229    float x,y;
  230    int max_per_line=4;
  231    char str[256];
  232    char datef[32];
  233 
  234    for (i=0; i<24; i++) {
  235       hours[i]=0;
  236    }
  237 
  238    /* We have to go through them twice, once for AM, and once for PM
  239     * This is because of the clipping */
  240    for (i=0; i<2; i++) {
  241       am=i%2;
  242       fprintf(out, "gsave\n");
  243       if (am) {
  244          clip_to_box(1.25, 0.5, 4.25, 9.5);
  245       } else {
  246          clip_to_box(5.0, 0.5, 8.0, 9.5);
  247       }
  248       for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
  249          if (temp_cel->mcale.cale.description == NULL) {
  250             continue;
  251          }
  252          if (temp_cel->mcale.cale.event) {
  253             strcpy(str, " ");
  254             if (!am) {
  255                continue;
  256             }
  257             x=indent1;
  258             y=default_y - defaults1 * step;
  259             defaults1++;
  260          } else {
  261             hour24 = temp_cel->mcale.cale.begin.tm_hour;
  262             if ((hour24 > 11) && (am)) {
  263                continue;
  264             }
  265             if ((hour24 < 12) && (!am)) {
  266                continue;
  267             }
  268 
  269             get_pref_time_no_secs(datef);
  270             strftime(str, sizeof(str), datef, &temp_cel->mcale.cale.begin);
  271 
  272             if (hour24 > 11) {
  273                x=indent2;
  274                y=top_y - (hour24 - 12) * 0.5 - (hours[hour24]) * step;
  275                hours[hour24]++;
  276                if (hours[hour24] > max_per_line) {
  277                   y=default_y - defaults2 * step;
  278                   defaults2++;
  279                }
  280             } else {
  281                x=indent1;
  282                y=top_y - (hour24) * 0.5 - (hours[hour24]) * step;
  283                hours[hour24]++;
  284                if (hours[hour24] > max_per_line) {
  285                   y=default_y - defaults1 * step;
  286                   defaults1++;
  287                }
  288             }
  289          }
  290          if (temp_cel->mcale.cale.description) {
  291             strcat(str, " ");
  292             strncat(str, temp_cel->mcale.cale.description, sizeof(str)-strlen(str)-2);
  293             str[128]='\0';
  294             /* FIXME: Add location in parentheses (loc) as the Palm does.
  295              * We would need to check strlen, etc., before adding */
  296          }
  297          if (y > 1.0) {
  298             puttext(x, y, str);
  299          } else {
  300             jp_logf(JP_LOG_WARN, "Too many appointments, dropping one\n");
  301          }
  302       }
  303       fprintf(out, "grestore\n");
  304    }
  305 
  306    return EXIT_SUCCESS;
  307 }
  308 
  309 int print_days_appts(struct tm *date)
  310 {
  311    CalendarEventList *ce_list;
  312 
  313    out = print_open();
  314    if (!out) {
  315       return EXIT_FAILURE;
  316    }
  317 
  318    ce_list = NULL;
  319 
  320    get_days_calendar_events2(&ce_list, date, 2, 2, 2, CATEGORY_ALL, NULL);
  321 
  322    print_dayview(date, ce_list);
  323 
  324    print_close(out);
  325 
  326    free_CalendarEventList(&ce_list);
  327 
  328    return EXIT_SUCCESS;
  329 }
  330 
  331 static int f_indent_print(FILE *f, int indent, char *str) {
  332    char *P;
  333    int i, col;
  334 
  335    col=indent;
  336    for (P=str; *P; P++) {
  337       col++;
  338       if ((*P==10) || (*P==13)) {
  339          fprintf(f, "%c", *P);
  340          for (i=indent; i; i--) {
  341             fprintf(f, " ");
  342          }
  343          col=indent;
  344          continue;
  345       }
  346       if (col>75) {
  347          fprintf(f, "\n");
  348          for (i=indent; i; i--) {
  349             fprintf(f, " ");
  350          }
  351          col=indent+1;
  352       }
  353       fprintf(f, "%c", *P);
  354    }
  355    return EXIT_SUCCESS;
  356 }
  357 
  358 /*----------------------------------------------------------------------
  359  * ps_strncat   Escapes brackets for printing in PostScript strings
  360  *----------------------------------------------------------------------*/
  361 
  362 void ps_strncat(char *dest, const char *src, int n)
  363 {
  364    int i = 0, j = 0;
  365    char *dest2;
  366    dest2 = strchr(dest, '\0');
  367    while (j < n) {
  368       if (src[i] == '\0') {
  369          dest2[j]='\0';
  370          break;
  371       }
  372       if (strchr("()", src[i]) != NULL) {
  373          if(j<n-1) dest2[j] = '\\'; else dest2[j]=' ';
  374          j++;
  375       }
  376       dest2[j] = src[i];
  377       i++;
  378       j++;
  379    }
  380 }
  381 
  382 /*----------------------------------------------------------------------
  383  * days_in_mon  Returns the number of days in the month containing the
  384  *              date passed in.
  385  *----------------------------------------------------------------------*/
  386 
  387 static int days_in_mon(struct tm *date)
  388 {
  389    int days_in_month[]={ 31,28,31,30,31,30,31,31,30,31,30,31 };
  390 
  391    if ((date->tm_year%4 == 0) &&
  392        !(((date->tm_year+1900)%100==0) && ((date->tm_year+1900)%400!=0))) {
  393        days_in_month[1]++;
  394    }
  395    return(days_in_month[date->tm_mon]);
  396 }
  397 
  398 /*----------------------------------------------------------------------
  399  * print_months_appts   Function to print the current month's
  400  *                      appointments.
  401  *----------------------------------------------------------------------*/
  402 
  403 static const char *MonthNames[] = {
  404    "January", "February", "March", "April", "May", "June", "July",
  405    "August", "September", "October", "November", "December"
  406 };
  407 
  408 int print_months_appts(struct tm *date_in, PaperSize paper_size)
  409 {
  410    CalendarEventList *ce_list;
  411    CalendarEventList *temp_cel;
  412    struct tm date;
  413    char desc[100];
  414    time_t ltime;
  415    int dow;
  416    int ndim;
  417    int n;
  418    long fdow;
  419    int mask;
  420 #ifdef ENABLE_DATEBK
  421    int cat_bit;
  422    int db3_type;
  423    long use_db3_tags;
  424    struct db4_struct db4;
  425 #endif
  426 #ifdef HAVE_LOCALE_H
  427    char *current_locale;
  428 #endif
  429 
  430    /*------------------------------------------------------------------
  431     * Set up the PostScript output file, and print the header to it.
  432     *------------------------------------------------------------------*/
  433    mask=0;
  434 
  435    time(&ltime);
  436 
  437 #ifdef ENABLE_DATEBK
  438    get_pref(PREF_USE_DB3, &use_db3_tags, NULL);
  439 #endif
  440 
  441 #ifdef HAVE_LOCALE_H
  442    current_locale = setlocale(LC_NUMERIC,"C");
  443 #endif
  444    if (! (out = print_open())) return(EXIT_FAILURE);
  445 
  446    fprintf(out,
  447            "%%!PS-Adobe-2.0\n"
  448            "%%%%Creator: J-Pilot\n"
  449            "%%%%CreationDate: %s"
  450            "%%%%DocumentData: Clean7Bit\n"
  451            "%%%%Orientation: Landscape\n\n"
  452            "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
  453            "%%%%Magnification: 1.0000\n"
  454            "%%%%Pages: 1\n"
  455            "%%%%EndComments\n"
  456            "%%%%BeginProlog\n"
  457            ,ctime(&ltime));
  458    fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[paper_size]);
  459    print_common_prolog(out);
  460    fprintf(out,
  461            "%%%%EndProlog\n"
  462            "%%%%BeginSetup\n");
  463    print_common_setup(out);
  464    print_month_header(out);
  465    fprintf(out,
  466            "%%%%EndSetup\n"
  467            "%%%%Page: 1 1\n\n");
  468 
  469    /*------------------------------------------------------------------
  470     * Extract the appointments
  471     *------------------------------------------------------------------*/
  472    ce_list = NULL;
  473    memcpy(&date, date_in, sizeof(struct tm));
  474    /* Get all of the appointments */
  475 
  476    get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
  477    get_month_info(date.tm_mon, 1, date.tm_year, &dow, &ndim);
  478    weed_calendar_event_list(&ce_list, date.tm_mon, date.tm_year, 0, &mask);
  479 
  480    /*------------------------------------------------------------------
  481     * Loop through the days in the month, printing appointments
  482     *------------------------------------------------------------------*/
  483    date.tm_mday=1;
  484    date.tm_sec=0;
  485    date.tm_min=0;
  486    date.tm_hour=11;
  487    date.tm_isdst=-1;
  488    mktime(&date);
  489 
  490    get_pref(PREF_FDOW, &fdow, NULL);
  491 
  492    fprintf(out,
  493            "(%s %d) %d (%s) (%s version %s) %ld InitialisePage\n\n",
  494            MonthNames[date_in->tm_mon], date_in->tm_year + 1900,
  495            date.tm_wday,
  496            ctime(&ltime),
  497            PN, VERSION, fdow);
  498 
  499    for (n=0, date.tm_mday=1; date.tm_mday<=ndim; date.tm_mday++, n++) {
  500       date.tm_sec=0;
  501       date.tm_min=0;
  502       date.tm_hour=11;
  503       date.tm_isdst=-1;
  504       date.tm_wday=0;
  505       date.tm_yday=1;
  506       mktime(&date);
  507 
  508       fprintf(out, "%%--------------------------------------------------\n"
  509               "%%Stuff for day %2d being printed\n", date.tm_mday);
  510       fprintf(out, "NextDay\n");
  511 
  512       for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
  513 #ifdef ENABLE_DATEBK
  514          if (use_db3_tags) {
  515             db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
  516             /* jp_logf(JP_LOG_DEBUG, "category = 0x%x\n", db4.category); */
  517             cat_bit=1<<db4.category;
  518             if (!(cat_bit & datebk_category)) {
  519                jp_logf(JP_LOG_DEBUG, "skipping rec not in this category\n");
  520                continue;
  521             }
  522          }
  523 #endif
  524          if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date)) {
  525             char tmp[20];
  526             char datef1[20];
  527             char datef2[20];
  528             tmp[0]='\0';
  529             if ( ! temp_cel->mcale.cale.event) {
  530                get_pref_time_no_secs(datef1);
  531                g_snprintf(datef2, sizeof(datef2), "(%s )", datef1);
  532                strftime(tmp, sizeof(tmp), datef2, &(temp_cel->mcale.cale.begin));
  533                tmp[19]='\0';
  534             }
  535             desc[0]='\0';
  536             if (temp_cel->mcale.cale.description) {
  537                ps_strncat(desc, temp_cel->mcale.cale.description, 100);
  538                desc[sizeof(desc)-1]='\0';
  539                /* FIXME: Add location in parentheses (loc) as the Palm does.
  540                 * We would need to check strlen, etc., before adding */
  541             }
  542             remove_cr_lfs(desc);
  543             fprintf(out, "%s (%s) %simedItem\n", tmp, desc,
  544                     (strlen(tmp) == 0) ? "Unt" : "T" );
  545          }
  546       }
  547    }
  548 
  549    /*------------------------------------------------------------------*/
  550    memcpy(&date, date_in, sizeof(struct tm));
  551    date.tm_mday = 1;    /* Go to the first of the month */
  552    mktime(&date);
  553    sub_months_from_date(&date, 1);
  554    strftime(desc, sizeof(desc), "(%B %Y) %w ", &date);
  555    fprintf(out, "\n\n%%----------------------------------------\n"
  556            "%% Now generate the small months\n\n"
  557            "%s %d ", desc, days_in_mon(&date));
  558 
  559    add_months_to_date(&date, 2);
  560    strftime(desc, sizeof(desc), "(%B %Y) %w ", &date);
  561    fprintf(out, "%s %d SmallMonths\n", desc, days_in_mon(&date));
  562 
  563    /*------------------------------------------------------------------*/
  564 
  565    free_CalendarEventList(&ce_list);
  566 
  567    fprintf(out, "grestore\n");
  568    print_logo(out, 20, 30, 0.35);
  569    fprintf(out, "\nshowpage\n");
  570    fprintf(out, "%%%%EOF\n");
  571 
  572    print_close(out);
  573 
  574 #ifdef HAVE_LOCALE_H
  575    setlocale(LC_NUMERIC, current_locale);
  576 #endif
  577    return EXIT_SUCCESS;
  578 }
  579 
  580 /*----------------------------------------------------------------------
  581  * reset_first_last     Routine to reset max/min appointment times
  582  *----------------------------------------------------------------------*/
  583 
  584 static void reset_first_last(void)
  585 {
  586    first_hour = 25;
  587    first_min  = 61;
  588    last_hour  = -1;
  589    last_min   = -1;
  590 }
  591 
  592 /*----------------------------------------------------------------------
  593  * check_first_last     Routine to track max/min appointment times
  594  *----------------------------------------------------------------------*/
  595 
  596 static void check_first_last(CalendarEventList *cel)
  597 {
  598    struct tm *ApptTime;
  599    ApptTime = &(cel->mcale.cale.begin);
  600    if (ApptTime->tm_hour == first_hour) {
  601       if (ApptTime->tm_min < first_min) first_min = ApptTime->tm_min;
  602    }
  603    else if (ApptTime->tm_hour < first_hour) {
  604       first_hour = ApptTime->tm_hour;
  605       first_min  = ApptTime->tm_min;
  606    }
  607 
  608    ApptTime = &(cel->mcale.cale.end);
  609    if (ApptTime->tm_hour == last_hour) {
  610       if (ApptTime->tm_min > last_min) last_min = ApptTime->tm_min;
  611    } else if (ApptTime->tm_hour > last_hour) {
  612       last_hour = ApptTime->tm_hour;
  613       last_min  = ApptTime->tm_min;
  614    }
  615 }
  616 
  617 /*----------------------------------------------------------------------
  618  * print_weeks_appts    Function to print a weeks appointments onto a
  619  *                      weekly plan. We assume that date_in is the chosen
  620  *                      first day of the week.
  621  *----------------------------------------------------------------------*/
  622 
  623 int print_weeks_appts(struct tm *date_in, PaperSize paper_size)
  624 {
  625    CalendarEventList *ce_list, *temp_cel;
  626    struct tm date;
  627    struct tm *today_date;
  628    char desc[256], short_date[32];
  629    int n;
  630    time_t ltime;
  631 #ifdef ENABLE_DATEBK
  632    int cat_bit;
  633    int db3_type;
  634    long use_db3_tags;
  635    struct db4_struct db4;
  636 #endif
  637 #ifdef HAVE_LOCALE_H
  638    char *current_locale;
  639 #endif
  640 
  641 #ifdef ENABLE_DATEBK
  642    get_pref(PREF_USE_DB3, &use_db3_tags, NULL);
  643 #endif
  644 #ifdef HAVE_LOCALE_H
  645    current_locale = setlocale(LC_NUMERIC,"C");
  646 #endif
  647 
  648    /*------------------------------------------------------------------
  649     * Set up the PostScript output file, and print the header to it.
  650     *------------------------------------------------------------------*/
  651    if (! (out = print_open())) return(EXIT_FAILURE);
  652 
  653    time(&ltime);
  654    fprintf(out,
  655            "%%!PS-Adobe-2.0\n"
  656            "%%%%Creator: J-Pilot\n"
  657            "%%%%CreationDate: %s"
  658            "%%%%DocumentData: Clean7Bit\n"
  659            "%%%%Orientation: Landscape\n"
  660            "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
  661            "%%%%Magnification: 1.0000\n"
  662            "%%%%Pages: 1\n"
  663            "%%%%EndComments\n"
  664            "%%%%BeginProlog\n"
  665            ,ctime(&ltime));
  666    /*------------------------------------------------------------------
  667     * These are preferences for page size (passed in), first and last
  668     * hours on the plan (default; scales if earlier or later are present),
  669     * and whether to print dashes across the page.
  670     *------------------------------------------------------------------*/
  671    fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[paper_size]);
  672    fprintf(out, "/FirstHour  9 def\n"
  673                 "/LastHour  22 def\n");
  674    fprintf(out, "/Dashes true def\n");
  675    print_common_prolog(out);
  676    fprintf(out,
  677            "%%%%EndProlog\n"
  678            "%%%%BeginSetup\n");
  679    print_common_setup(out);
  680    print_week_header(out);
  681    fprintf(out,
  682            "%%%%EndSetup\n"
  683            "%%%%Page: 1 1\n\n");
  684 
  685    /*------------------------------------------------------------------
  686     * Run through the appointments, looking for earliest and latest
  687     *------------------------------------------------------------------*/
  688    ce_list = NULL;
  689    get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
  690    reset_first_last();
  691 
  692    memcpy(&date, date_in, sizeof(struct tm));
  693    for (n = 0; n < 7; n++, add_days_to_date(&date, 1)) {
  694       for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
  695 #ifdef ENABLE_DATEBK
  696          if (use_db3_tags) {
  697             db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
  698             cat_bit=1<<db4.category;
  699             if (!(cat_bit & datebk_category)) continue;
  700          }
  701 #endif
  702          if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date))
  703             if (! temp_cel->mcale.cale.event)
  704                check_first_last(temp_cel);
  705       }
  706    }
  707    if (last_min > 0) last_hour++;
  708 
  709    /*------------------------------------------------------------------
  710     * Now put in the finishing touches to the header, and kick-start
  711     * the printing process
  712     *------------------------------------------------------------------*/
  713 
  714    today_date = localtime(&ltime);
  715    fprintf(out,
  716            "%%------------------------------------------------------------\n"
  717            "%% This is today's date, the date of printing, plus the hour\n"
  718            "%% before & after the first and last appointments, respectively\n"
  719            "%d %d %d %d %d startprinting\n\n",
  720            today_date->tm_mday, today_date->tm_mon + 1,
  721            today_date->tm_year + 1900, first_hour, last_hour);
  722    fprintf(out, "( by %s version %s) show\n", PN, VERSION);
  723 
  724    print_logo(out, 20, 30, 0.35);
  725 
  726    /*------------------------------------------------------------------
  727     * Run through the appointments, printing them out
  728     *------------------------------------------------------------------*/
  729    free_CalendarEventList(&ce_list);
  730    ce_list = NULL;
  731 
  732    /* Get all of the appointments */
  733    get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
  734 
  735    /* iterate through seven days */
  736    memcpy(&date, date_in, sizeof(struct tm));
  737 
  738    for (n = 0; n < 7; n++, add_days_to_date(&date, 1)) {
  739       strftime(short_date, sizeof(short_date), "%a, %d %b, %Y", &date);
  740       fprintf(out, "%d startday\n(%s) dateline\n", n, short_date);
  741 
  742       for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
  743 #ifdef ENABLE_DATEBK
  744          if (use_db3_tags) {
  745             db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
  746             jp_logf(JP_LOG_DEBUG, "category = 0x%x\n", db4.category);
  747             cat_bit=1<<db4.category;
  748             if (!(cat_bit & datebk_category)) {
  749                jp_logf(JP_LOG_DEBUG, "skip rec not in this category\n");
  750                continue;
  751             }
  752          }
  753 #endif
  754          if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date)) {
  755             memset(desc, 0, sizeof(desc));
  756             memset(short_date, 0, sizeof(short_date));
  757 
  758             if ( ! temp_cel->mcale.cale.event)
  759               {
  760                  char t1[6], t2[6], ht[3], mt[3];
  761                  int j, m;
  762 
  763                  strftime(ht, sizeof(ht), "%H", &(temp_cel->mcale.cale.begin));
  764                  strftime(mt, sizeof(mt), "%M", &(temp_cel->mcale.cale.begin));
  765                  m = atoi(mt);
  766                  snprintf(t1, sizeof(t1), "%s.%02d", ht, (int)((m * 100.)/60));
  767 
  768                  strftime(ht, sizeof(ht), "%H", &(temp_cel->mcale.cale.end));
  769                  strftime(mt, sizeof(mt), "%M", &(temp_cel->mcale.cale.end));
  770                  m = atoi(mt);
  771                  snprintf(t2, sizeof(t2), "%s.%02d", ht, (int)((m * 100.)/60));
  772                  sprintf(short_date, "%s %s ", t1, t2);
  773                  for (j=0; j<30;j++) short_date[j] =tolower(short_date[j]);
  774               }
  775             if (temp_cel->mcale.cale.description) {
  776                ps_strncat(desc, temp_cel->mcale.cale.description, 250);
  777                /* FIXME: Add location in parentheses (loc) as the Palm does.
  778                 * We would need to check strlen, etc., before adding */
  779                remove_cr_lfs(desc);
  780             }
  781             fprintf(out, "%s (%s) itemline\n", short_date, desc);
  782          }
  783       }
  784    }
  785    free_CalendarEventList(&ce_list);
  786    fprintf(out, "\nfinishprinting\n");
  787    fprintf(out, "%%%%EOF\n");
  788    print_close(out);
  789 
  790 #ifdef HAVE_LOCALE_H
  791    setlocale(LC_ALL, current_locale);
  792 #endif
  793    return EXIT_SUCCESS;
  794 }
  795 
  796 /*
  797  * Address code
  798  */
  799 
  800 static int print_address_header(void)
  801 {
  802    time_t ltime;
  803    struct tm *date;
  804    const char *svalue;
  805    char str[256];
  806 
  807    time(&ltime);
  808    date = localtime(&ltime);
  809 
  810    get_pref(PREF_SHORTDATE, NULL, &svalue);
  811    strftime(str, sizeof(str), svalue, date);
  812 
  813    fprintf(out,
  814            "%%!PS-Adobe-2.0\n"
  815            "%%%%Creator: J-Pilot\n"
  816            "%%%%CreationDate: %s"
  817            "%%%%DocumentData: Clean7Bit\n"
  818            /* XXX Title */
  819            "%%%%Orientation: Portrait\n"
  820            /* XXX BoundingBox */
  821            "%%DocumentFonts: Times-Roman Times-Bold "
  822            "Courier Courier-Bold ZapfDingbats\n"
  823            "%%%%Magnification: 1.0000\n"
  824            "%%%%BoundingBox: 36 36 576 756\n"
  825            "%%%%EndComments\n",
  826            ctime(&ltime));
  827    fprintf(out,
  828            "%%%%BeginProlog\n"
  829            "%%%%BeginResource: procset\n"
  830            "/inch {72 mul} def\n"
  831            "/left {0.5 inch} def\n"
  832            "/bottom {1.0 inch} def\n"
  833            "/bottom_hline {2.0 inch} def\n"
  834            "/footer {0.9 inch} def\n"
  835            "/top {10.5 inch 14 sub} def\n"
  836            "/buffer 1024 string def\n"
  837            "/scratch 128 string def\n"
  838            "/printobject {\n"
  839            "dup 128 string cvs dup (--nostringval--) eq {\n"
  840            "pop type24 string cvs\n"
  841            "}{\n"
  842            "exch pop\n"
  843            "} ifelse\n"
  844            "} bind def\n");
  845    /* Checkbox stuff */
  846    fprintf(out,
  847            "/checkboxcheck {\n"
  848            "%%currentpoint 6 add moveto\n"
  849            "%%4 -5 rlineto\n"
  850            "%%6 12 rlineto\n"
  851            "/ZapfDingbats 14 selectfont (4) show\n" /* or 3 if you prefer */
  852            "} bind def\n"
  853            "/checkboxbox {\n"
  854            "8 0 rlineto\n"
  855            "0 8 rlineto\n"
  856            "-8 0 rlineto\n"
  857            "0 -8 rlineto\n"
  858            "} bind def\n"
  859            "/checkbox {\n"
  860            "currentpoint\n"
  861            "gsave\n"
  862            "newpath\n"
  863            "moveto\n"
  864            "1 setlinewidth\n"
  865            "checkboxbox\n"
  866            "stroke\n"
  867            "grestore\n"
  868            "} bind def\n"
  869            "/checkedbox {\n"
  870            "currentpoint\n"
  871            "gsave\n"
  872            "newpath\n"
  873            "moveto\n"
  874            "1 setlinewidth\n"
  875            "checkboxbox\n"
  876            "checkboxcheck\n"
  877            "stroke\n"
  878            "grestore\n"
  879            "} bind def\n"
  880            );
  881 
  882    /* Recode font function */
  883    fprintf(out,
  884            "/Recode {\n"
  885            "exch\n"
  886            "findfont\n"
  887            "dup length dict\n"
  888            "begin\n"
  889            "{ def\n"
  890            "} forall\n"
  891            "/Encoding ISOLatin1Encoding def\n"
  892            "currentdict\n"
  893            "end\n"
  894            "definefont pop\n"
  895            "} bind def\n");
  896    fprintf(out,
  897            "/Times-Roman  /Times-Roman-ISOLatin1 Recode\n"
  898            "/Courier      /Courier-ISOLatin1 Recode\n"
  899            "/Courier-Bold /Courier-Bold-ISOLatin1 Recode\n");
  900    fprintf(out,
  901           "/hline {\n"
  902            "currentpoint 1 add currentpoint 1 add\n"
  903            "currentpoint 4 add currentpoint 4 add\n"
  904            "gsave\n"
  905            "newpath\n"
  906            "moveto\n"
  907            "exch\n"
  908            "1.0 inch add\n"
  909            "exch\n"
  910            "7 setlinewidth\n"
  911            "lineto\n"
  912            "stroke\n"
  913            "%%\n"
  914            "newpath\n"
  915            "moveto\n"
  916            "exch\n"
  917            "7.5 inch add\n"
  918            "exch\n"
  919            "1 setlinewidth\n"
  920            "lineto\n"
  921            "stroke\n"
  922            "grestore\n"
  923            "} bind def\n"
  924            "%%\n"
  925            "%%\n");
  926    fprintf(out,
  927            "/setup\n"
  928            "{\n"
  929            "/Times-Roman-ISOLatin1 10 selectfont\n"
  930            "left footer moveto\n"
  931            "(%s) show\n"
  932            "7.5 inch footer moveto\n"
  933            "(J-Pilot) show\n"
  934            "%% This assumes that the prev page number is on the stack\n"
  935            "4.25 inch footer moveto\n"
  936            "1 add dup printobject show\n"
  937            "/Courier-ISOLatin1 12 selectfont\n"
  938            "left top moveto\n"
  939            "} bind def\n"
  940            "/printit\n"
  941            "{\n"
  942            "{ %%loop\n"
  943            "currentfile buffer readline { %%ifelse\n"
  944            "("Q_FLAG_CHAR"LINEFEED) search { %%if\n"
  945            "pop pop pop showpage setup ( )\n"
  946            "currentpoint 14 add moveto\n"
  947            "} if\n"
  948            "("Q_FLAG_CHAR"HLINE) search { %%if\n"
  949            "currentpoint exch pop bottom_hline le { %%if\n"
  950            "pop pop pop\n"
  951            "showpage setup\n"
  952            "0 0 0\n"
  953            "} if\n"
  954            "hline\n"
  955            "pop pop pop ( )\n"
  956            "} if\n"
  957            "("Q_FLAG_CHAR"END) search { %%if\n"
  958            "   showpage stop\n"
  959            "} if\n"
  960            "("Q_FLAG_CHAR"C12) search {\n"
  961            "/Courier-ISOLatin1 12 selectfont\n"
  962            "currentpoint 14 add moveto\n"
  963            "pop pop pop ( )\n"
  964            "} if\n"
  965            "("Q_FLAG_CHAR"CB12) search {\n"
  966            "/Courier-Bold-ISOLatin1 12 selectfont\n"
  967            "currentpoint 14 add moveto\n"
  968            "pop pop pop ( )\n"
  969            "} if\n",
  970            str
  971            );
  972    /* Check box */
  973    fprintf(out,
  974            "("Q_FLAG_CHAR"CHECKBOX) search {\n"
  975            "currentpoint exch pop bottom_hline le {\n"
  976            "pop pop pop\n"
  977            "showpage setup\n"
  978            "0 0 0\n"
  979            "} if\n"
  980            "checkbox\n"
  981            "currentpoint 14 add moveto\n"
  982            "pop pop pop ( )\n"
  983            "} if\n"
  984            );
  985    /* Check box */
  986    fprintf(out,
  987            "("Q_FLAG_CHAR"CHECKEDBOX) search {\n"
  988            "currentpoint exch pop bottom_hline le {\n"
  989            "pop pop pop\n"
  990            "showpage setup\n"
  991            "0 0 0\n"
  992            "} if\n"
  993            "checkedbox\n"
  994            "currentpoint 14 add moveto\n"
  995            "pop pop pop ( )\n"
  996            "} if\n"
  997            );
  998    fprintf(out,
  999            "%%%%EndResource\n"
 1000            "%%%%EndProlog\n"); /* XXX not exactly sure about position */
 1001 
 1002    fprintf(out,
 1003            "gsave show grestore\n"
 1004            "currentpoint 14 sub moveto\n"
 1005            "currentpoint exch pop bottom le { %%if\n"
 1006            "showpage setup\n"
 1007            "} if\n"
 1008            "}{ %%else\n"
 1009            "showpage exit\n"
 1010            "} ifelse\n"
 1011            "} loop\n"
 1012            "} bind def\n"
 1013            "0 %%The page number minus 1\n"
 1014            "setup printit\n"
 1015            );
 1016    return EXIT_SUCCESS;
 1017 }
 1018 
 1019 
 1020 int print_contacts(ContactList *contact_list, 
 1021                    struct ContactAppInfo *contact_app_info,
 1022                    address_schema_entry *schema, int schema_size)
 1023 {
 1024    long one_rec_per_page;
 1025    long lines_between_recs;
 1026    ContactList *temp_cl;
 1027    MyContact *mcont;
 1028    int show1, show2, show3;
 1029    int i;
 1030    int address_i, phone_i, IM_i;
 1031    char str[100];
 1032    char spaces[24];
 1033    char birthday_str[255];
 1034    const char *pref_date;
 1035    char *utf;
 1036    long char_set;
 1037 #ifdef HAVE_LOCALE_H
 1038    char *current_locale;
 1039 #endif
 1040 
 1041    out = print_open();
 1042    if (!out) {
 1043       return EXIT_FAILURE;
 1044    }
 1045 
 1046 #ifdef HAVE_LOCALE_H
 1047    current_locale = setlocale(LC_NUMERIC,"C");
 1048 #endif
 1049 
 1050    memset(spaces, ' ', sizeof(spaces));
 1051 
 1052    get_pref(PREF_CHAR_SET, &char_set, NULL);
 1053 
 1054    print_address_header();
 1055 
 1056    switch (addr_sort_order) {
 1057     case SORT_BY_LNAME:
 1058     default:
 1059       show1=contLastname;
 1060       show2=contFirstname;
 1061       show3=contCompany;
 1062       break;
 1063     case SORT_BY_FNAME:
 1064       show1=contFirstname;
 1065       show2=contLastname;
 1066       show3=contCompany;
 1067       break;
 1068     case SORT_BY_COMPANY:
 1069       show1=contCompany;
 1070       show2=contLastname;
 1071       show3=contFirstname;
 1072       break;
 1073    }
 1074 
 1075    get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
 1076    get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
 1077 
 1078    for (temp_cl = contact_list; temp_cl; temp_cl=temp_cl->next) {
 1079 
 1080       fprintf(out, "%cHLINE\n", FLAG_CHAR);
 1081 
 1082       str[0]='\0';
 1083       if (temp_cl->mcont.cont.entry[show1] || temp_cl->mcont.cont.entry[show2]) {
 1084          if (temp_cl->mcont.cont.entry[show1] && temp_cl->mcont.cont.entry[show2]) {
 1085             g_snprintf(str, sizeof(str), "%s, %s", temp_cl->mcont.cont.entry[show1], temp_cl->mcont.cont.entry[show2]);
 1086          }
 1087          if (temp_cl->mcont.cont.entry[show1] && ! temp_cl->mcont.cont.entry[show2]) {
 1088             strncpy(str, temp_cl->mcont.cont.entry[show1], 48);
 1089          }
 1090          if (! temp_cl->mcont.cont.entry[show1] && temp_cl->mcont.cont.entry[show2]) {
 1091             strncpy(str, temp_cl->mcont.cont.entry[show2], 48);
 1092          }
 1093       } else if (temp_cl->mcont.cont.entry[show3]) {
 1094             strncpy(str, temp_cl->mcont.cont.entry[show3], 48);
 1095       } else {
 1096             strcpy(str, "-Unnamed-");
 1097       }
 1098 
 1099       courier_bold_12();
 1100       fprintf(out, "%s\n", str);
 1101       courier_12();
 1102 
 1103       mcont = &(temp_cl->mcont);
 1104       address_i=phone_i=IM_i=0;
 1105       for (i=0; i<schema_size; i++) {
 1106          /* Get the entry texts */
 1107          if (mcont->cont.entry[schema[i].record_field]) {
 1108             switch (schema[i].type) {
 1109              case ADDRESS_GUI_IM_MENU_TEXT:
 1110                g_snprintf(str, 18, "%s:%s", contact_app_info->IMLabels[mcont->cont.IMLabel[IM_i]], spaces);
 1111                fprintf(out, "%s", str);
 1112                IM_i++;
 1113                break;
 1114              case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
 1115                g_snprintf(str, 18, "%s:%s", contact_app_info->phoneLabels[mcont->cont.phoneLabel[phone_i]], spaces);
 1116                fprintf(out, "%s", str);
 1117                phone_i++;
 1118                break;
 1119              case ADDRESS_GUI_ADDR_MENU_TEXT:
 1120                g_snprintf(str, 18, "%s:%s", contact_app_info->addrLabels[mcont->cont.addressLabel[address_i]], spaces);
 1121                fprintf(out, "%s", str);
 1122                address_i++;
 1123                break;
 1124              default:
 1125                if (contact_app_info->labels[schema[i].record_field]) {
 1126                   utf = charset_p2newj(contact_app_info->labels[schema[i].record_field], 16, char_set);
 1127                   g_snprintf(str, 18, "%s:%s", utf, spaces);
 1128                   fprintf(out, "%s", str);
 1129                   g_free(utf);
 1130                }
 1131                else {
 1132                   g_snprintf(str, 18, ":%s", spaces);
 1133                   fprintf(out, "%s", str);
 1134                }
 1135             }
 1136             switch (schema[i].type) {
 1137              case ADDRESS_GUI_LABEL_TEXT:
 1138              case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
 1139              case ADDRESS_GUI_IM_MENU_TEXT:
 1140              case ADDRESS_GUI_ADDR_MENU_TEXT:
 1141              case ADDRESS_GUI_WEBSITE_TEXT:
 1142                f_indent_print(out, 17, mcont->cont.entry[schema[i].record_field]);
 1143                fprintf(out, "\n");
 1144                break;
 1145              case ADDRESS_GUI_BIRTHDAY:
 1146                if (mcont->cont.birthdayFlag) {
 1147                   birthday_str[0]='\0';
 1148                   get_pref(PREF_SHORTDATE, NULL, &pref_date);
 1149                   strftime(birthday_str, sizeof(birthday_str), pref_date, &(mcont->cont.birthday));
 1150                   g_snprintf(str, 18, "%s:%s", contact_app_info->labels[schema[i].record_field] ? contact_app_info->labels[schema[i].record_field] : "",
 1151                              spaces);
 1152                   fprintf(out, "%s", str);
 1153                   f_indent_print(out, 17, birthday_str);
 1154                   fprintf(out, "\n");
 1155                }
 1156                break;
 1157             }
 1158          }
 1159       }
 1160 
 1161       if (one_rec_per_page) {
 1162          fprintf(out, "%cLINEFEED\n", FLAG_CHAR);
 1163       } else {
 1164          for (i=lines_between_recs; i>0; i--) {
 1165             fprintf(out, "\n");
 1166          }
 1167       }
 1168    }
 1169 
 1170    print_close(out);
 1171 
 1172 #ifdef HAVE_LOCALE_H
 1173    setlocale(LC_ALL, current_locale);
 1174 #endif
 1175 
 1176    return EXIT_SUCCESS;
 1177 }
 1178 
 1179 /*
 1180  * ToDo code
 1181  */
 1182 int print_todos(ToDoList *todo_list, char *category_name)
 1183 {
 1184    long one_rec_per_page;
 1185    long lines_between_recs;
 1186    ToDoList *temp_l;
 1187    struct ToDo *todo;
 1188    int indent;
 1189    const char *datef;
 1190    char str[100];
 1191    time_t ltime;
 1192    struct tm *now;
 1193 #ifdef HAVE_LOCALE_H
 1194    char *current_locale;
 1195 #endif
 1196 
 1197    out = print_open();
 1198    if (!out) {
 1199       return EXIT_FAILURE;
 1200    }
 1201 
 1202 #ifdef HAVE_LOCALE_H
 1203    current_locale = setlocale(LC_NUMERIC,"C");
 1204 #endif
 1205 
 1206    fprintf(out, "%%!PS-Adobe-2.0\n\n"
 1207            "/PageSize (%s) def\n\n", PaperSizes[PAPER_Letter]);
 1208    print_common_prolog(out);
 1209    print_common_setup(out);
 1210    fprintf(out, "/CategoryName (%s) def\n", category_name);
 1211    print_todo_header(out);
 1212 
 1213    get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
 1214    get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
 1215 
 1216    get_pref(PREF_SHORTDATE, NULL, &datef);
 1217    time(&ltime);
 1218    now = localtime(&ltime);
 1219    strftime(str, sizeof(str), datef, now);
 1220    indent=strlen(str) + 8;
 1221 
 1222    for (temp_l = todo_list; temp_l; temp_l=temp_l->next) {
 1223       todo = &(temp_l->mtodo.todo);
 1224 
 1225       fprintf(out, todo->complete ? "true  " : "false ");
 1226 
 1227       fprintf(out, "%d ", todo->priority);
 1228 
 1229       if (todo->indefinite) {
 1230          sprintf(str, "%s           ", "No Due");
 1231          str[indent-8]='\0';
 1232       } else {
 1233          strftime(str, sizeof(str), datef, &(todo->due));
 1234       }
 1235       fprintf(out, "(%s) ", str);
 1236 
 1237       if (todo->description) {
 1238          int len;
 1239          char *buf;
 1240 
 1241          len = strlen(todo->description);
 1242          buf = malloc(2 * len + 1);
 1243          memset(buf, 0, 2 * len + 1);
 1244          ps_strncat(buf, todo->description, 2 * len);
 1245 
 1246          fprintf(out, "(%s) ", buf);
 1247          free(buf);
 1248       } else {
 1249          fprintf(out, "() ");
 1250       }
 1251 
 1252       if ((todo->note) && todo->note[0]) {
 1253          int len;
 1254          char *buf;
 1255 
 1256          len = strlen(todo->note);
 1257          buf = malloc(2 * len + 1);
 1258          memset(buf, 0, 2 * len + 1);
 1259          ps_strncat(buf, todo->note, 2 * len);
 1260 
 1261          fprintf(out, "(%s) ", buf);
 1262          free(buf);
 1263       } else {
 1264          fprintf(out, "()");
 1265       }
 1266       fprintf(out, " Todo\n");
 1267 
 1268       if (one_rec_per_page) {
 1269          fprintf(out, "NewPage\n");
 1270       }
 1271    }
 1272    fprintf(out, "showpage\n");
 1273 
 1274    print_close(out);
 1275 
 1276 #ifdef HAVE_LOCALE_H
 1277    setlocale(LC_ALL, current_locale);
 1278 #endif
 1279 
 1280    return EXIT_SUCCESS;
 1281 }
 1282 /*
 1283  * Memo code
 1284  */
 1285 int print_memos(MemoList *memo_list)
 1286 {
 1287    long one_rec_per_page;
 1288    long lines_between_recs;
 1289    MemoList *temp_l;
 1290    struct Memo *memo;
 1291    int i;
 1292 #ifdef HAVE_LOCALE_H
 1293    char *current_locale;
 1294 #endif
 1295 
 1296    out = print_open();
 1297    if (!out) {
 1298       return EXIT_FAILURE;
 1299    }
 1300 
 1301 #ifdef HAVE_LOCALE_H
 1302    current_locale = setlocale(LC_NUMERIC,"C");
 1303 #endif
 1304 
 1305    print_address_header();
 1306 
 1307    get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
 1308    get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
 1309 
 1310    courier_12();
 1311 
 1312    for (temp_l = memo_list; temp_l; temp_l=temp_l->next) {
 1313       memo = &(temp_l->mmemo.memo);
 1314 
 1315       if (memo->text) {
 1316          fprintf(out, "%cHLINE\n", FLAG_CHAR);
 1317          f_indent_print(out, 0, memo->text);
 1318          fprintf(out, "\n");
 1319       }
 1320 
 1321       if (one_rec_per_page) {
 1322          fprintf(out, "%cLINEFEED\n", FLAG_CHAR);
 1323       } else {
 1324          for (i=lines_between_recs; i>0; i--) {
 1325             fprintf(out, "\n");
 1326          }
 1327       }
 1328    }
 1329 
 1330    fprintf(out, "%cEND\n", FLAG_CHAR);
 1331 
 1332 #ifdef HAVE_LOCALE_H
 1333    setlocale(LC_ALL, current_locale);
 1334 #endif
 1335 
 1336    print_close(out);
 1337 
 1338    return EXIT_SUCCESS;
 1339 }
 1340