Subversion Repositories svn1-original

Rev

Rev 162 | Rev 178 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
95 - 1
/*************************************************************************
2
 *          Copyright (C) 1995 Embedded Solutions
3
 *                      All rights reserved
4
 *
5
 * file:        src\print.c
6
 *
7
 * purpose: Module to interface to the printer channel (file)
8
 *
9
 * functions
10
 *      open_printer            - Open the printer
11
 *      close_printer           - Close the printer
12
 *      print                   - Print to to the printer
13
 *      printbanner             - Print a page banner
14
 *
15
 * programmer: David Purdie
16
 *
17
 * revision date        by      reason
18
 *  00.0    27/01/95    DDP     Tidies up the program and formatted the file
19
 *
20
 **************************************************************************/
21
 
22
#include    <stdio.h>
23
#include    <time.h>
24
#include    <stdarg.h>
174 - 25
#include    "mainwindow.h"
95 - 26
 
27
#include    "consts.h"
28
#include    "structs.h"
29
#include    "proto.h"
30
 
31
FILE       *pfile;                               /* Fd of the printer channel */
32
long        pri_time;                            /* Time printer is opened - for banners */
33
int         print_width;                         /* Width of the printout */
34
report_type print_html = text;                   /* Printing with HTML */
35
int         print_col = 0;                       /* Current print column */
36
int         print_line = 0;                      /* Current print line */
37
int         print_underline_start;               /* Start of underline */
38
int         print_underline_end;                 /* End of underline */
39
long        print_current_colour;                /* Current printing colour */
40
 
41
/*========================================================================
42
 *
43
 *  Open the printer
44
 *
45
 *  Purpose:
46
 *      This function is called to open the printer and prepare to print
47
 *
48
 *  Parameters:
49
 *      name        Name of print file
50
 *      ext         Ext of the print file
51
 *      width       Width of the printed file
52
 *      html        Printing in HTML mode
53
 *
54
 *  Returns:
55
 *      TRUE if the printer can be attached
56
 *
57
 *
58
 *  Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions
59
 *========================================================================*/
60
 
61
bool open_printer( const char *name, const char *ext, int width, report_type html, const char *title )
62
{
63
    char    *pname;
64
 
65
    /*
66
    **  Determine the name of the file
67
    **  May need to modify the extension if it is an HTML file
68
    */
69
    if ( html )
70
    {
71
        if ( html == printed )
72
            pname = p_filename( name[0] ? name : filebase, ext ,"prn.html" );
73
        else
74
            pname = p_filename( name[0] ? name : filebase, ext ,"html" );
75
    }
76
    else
77
    {
78
        pname = p_filename( filebase, name[0] ? name : "", ext[0] ? ext : "lst" );
79
    }
80
 
81
    /*
82
    **  Now use basic function
83
    */
84
    return open_printer_name (pname, width, html, title );
85
}
86
 
87
/*----------------------------------------------------------------------------
88
 * FUNCTION           : open_printer_name
89
 *
90
 * DESCRIPTION        : Open a printer with a known name
91
 *
92
 *      This function is called to open the printer and prepare to print
93
 *
94
 *  Parameters:
95
 *      pname       Name of print file
96
 *      width       Width of the printed file
97
 *      html        Printing in HTML mode
98
 *
99
 *  Returns:
100
 *      TRUE if the printer can be attached
101
 *
102
 *
103
 *  Note: Use an "htm" file extension as DOS cannot handle 4 letter extensions
104
----------------------------------------------------------------------------*/
105
 
106
bool open_printer_name( const char *pname, int width, report_type html, const char *title )
107
{
108
    print_width = width ? width : 80;
109
    print_col = 0;
110
    print_line = 0;
111
    print_underline_start = -1;
112
    print_underline_end = -1;
113
    print_current_colour = 0;
114
 
115
    /*
116
    **  Open the printer
117
    **  Ensure that it is opened in text mode
118
    */
119
    if( ( pfile = fopen( pname, "wt" ) ) != NULL )
120
    {
121
        time( &pri_time );                       /* Latch the time */
122
 
123
        /*
124
        **  Print out the HTML file header
125
        */
126
        if ( html )
127
        {
128
            print( "<HTML>\n" );
129
            print( "<HEAD>\n" );
130
            print( "<TITLE>%s - %s</TITLE>\n", config.event_name, title );
131
//            print( "<LINK rel=\"stylesheet\" href=\"brmr.css\" type=\"text/css\">\n");
132
            print( "</HEAD>\n" );
133
            print( "<BODY LANG=\"en-US\">\n" );
134
            print( "<PRE>" );
135
            print_html = html;
136
        }
137
 
138
        /*
139
        **  Print out a common banner
140
        */
141
        printbanner(title);
142
    }
143
    else
144
    {
174 - 145
        MainWindow::showMessage("Printer not available");
146
        //beep();                                /* Printer not available */
147
        //printf( "Printer not available" );
162 david 148
        //flush_out();
174 - 149
        //sleep( 5 );
95 - 150
    }
151
    return ( pfile != 0 );
152
}
153
 
154
/*========================================================================
155
 *
156
 *  Close the printer
157
 *
158
 *  Purpose:
159
 *      This function is called to close and release the printer
160
 *      All reports are terminated with a formfeed
161
 *
162
 *  Parameters:
163
 *      None
164
 *
165
 *  Returns:
166
 *      TRUE if the printer channel can be released
167
 *
168
 *========================================================================*/
169
 
170
bool close_printer(void)
171
{
172
    if ( print_html )
173
    {
174
        print_html = text;
175
        print( "</PRE>\n" );
176
        print( "</BODY>\n" );
177
        print( "</HTML>\n" );
178
    }
179
    else
180
    {
181
        print( "\014" );
182
    }
183
    fclose( pfile );
184
    return ( TRUE );
185
}
186
 
187
/*========================================================================
188
 *
189
 *  Print to to the printer
190
 *
191
 *  Purpose:
192
 *      This function is called to do print data on the printer
193
 *      Track current character index so as to assist in tracking the
194
 *      use of underline.
195
 *
196
 *  Assume:
197
 *      New lines are at the end of a line printed. This does allow for
198
 *      a single new-line.
199
 *
200
 *
201
 *  Parameters:
202
 *      Standard printf type parameters
203
 *
204
 *  Returns:
205
 *      TRUE : Operation was succesful
206
 *
207
 *========================================================================*/
208
 
209
int print( const char *format, ... )
210
{
211
    va_list     ap;
212
    char        pp[200];
213
    int         len;
214
    bool        eol = FALSE;
215
 
216
 
217
    /*
218
    **  If this is the start of a new line then we may need to colour it
219
    */
220
    if ( print_col == 0 && print_html && (print_line & 1) )
221
    {
222
        print_colour( HTML_COLOUR_GREEN );
223
    }
224
 
225
    /*
226
    **  If this is the start of a new line then we may need to perform
227
    **  a perf-skip
228
    */
229
    if ( print_col == 0 && print_line && ! print_html && config.lines_per_page && config.perf_skip )
230
    {
231
        if ( 0 == ((print_line + 2) % (config.lines_per_page - config.perf_skip)) )
232
        {
233
            int count = config.perf_skip;
234
            while ( count-- )
235
                fwrite( "\n", 1, 1, pfile );
236
        }
237
    }
238
 
239
    va_start( ap, format );
240
    len = vsprintf( pp, format, ap );
241
    va_end( ap );
242
 
243
    /*
244
    **  Detect the end of a line and flag for later processing
245
    */
246
    if ( len > 0 && pp[len - 1] == '\n' )
247
    {
248
        len--;
249
        eol = TRUE;
250
    }
251
 
252
    if ( len )
253
    {
254
        fwrite( pp, 1, len, pfile );
255
        print_col += len;
256
    }
257
 
258
    /*
259
    **  Perform End of Line operation before printing the final newline
260
    */
261
    if ( eol )
262
    {
263
        print_line++;
264
 
265
        /*
266
        **  Detect the end of a non-HTML underline
267
        */
268
        print_underline ( FALSE );
269
        if ( print_underline_start < print_underline_end )
270
        {
271
            int length;
272
 
273
            fwrite( "\n", 1, 1, pfile );
274
 
275
            length = print_underline_start;
276
            while( length-- )
277
                fwrite( " ", 1, 1, pfile );
278
 
279
            length = print_underline_end - print_underline_start;
280
            while ( length-- )
281
                fwrite( "=", 1, 1, pfile );
282
        }
283
 
284
        print_underline_start = -1;
285
        print_underline_end = -1;
286
        print_col = 0;
287
 
288
        /*
289
        **  Track the background colour
290
        */
291
        if ( print_html )
292
        {
293
            print_colour( 0 );
294
        }
295
 
296
        /*
297
        **  Now print the final newline
298
        */
299
        fwrite( "\n", 1, 1, pfile );
300
        len ++;
301
    }
302
 
303
    return ( len );
304
}
305
 
306
/*========================================================================
307
 *
308
 *  Print to to the printer
309
 *
310
 *  Purpose:
311
 *      This function is called to do print data on the printer
312
 *
313
 *  Assume:
314
 *      One CSV field per print
315
 *      New lines are at the end of a line printed. This does allow for
316
 *      a single new-line.
317
 *
318
 *
319
 *  Parameters:
320
 *      Standard printf type parameters
321
 *
322
 *  Returns:
323
 *      TRUE : Operation was succesful
324
 *
325
 *========================================================================*/
326
 
327
int csv_print( const char *format, ... )
328
{
329
    va_list     ap;
330
    char        pp[200];
331
    int         len;
332
    bool        eol = FALSE;
333
 
334
 
335
    va_start( ap, format );
336
    len = vsprintf( pp, format, ap );
337
    va_end( ap );
338
 
339
    /*
340
    **  Detect the end of a line and flag for later processing
341
    */
342
    if ( len > 0 && pp[len - 1] == '\n' )
343
    {
344
        len--;
345
        eol = TRUE;
346
    }
347
 
348
    if ( ! eol )
349
    {
350
        if ( print_col )
351
            fwrite( ",", 1, 1, pfile );
352
        fwrite( "\"", 1, 1, pfile );
353
        fwrite( pp, 1, len, pfile );
354
        print_col += len;
355
        fwrite( "\"", 1, 1, pfile );
356
    }
357
 
358
    /*
359
    **  Perform End of Line operation before printing the final newline
360
    */
361
    if ( eol )
362
    {
363
        print_line++;
364
        print_col = 0;
365
 
366
        /*
367
        **  Now print the final newline
368
        */
369
        fwrite( "\n", 1, 1, pfile );
370
        len ++;
371
    }
372
 
373
    return ( len );
374
}
375
 
376
 
377
/*========================================================================
378
 *
379
 *  Print to to the printer without any frills
380
 *
381
 *  Purpose:
382
 *      This function is called to do print data on the printer
383
 *
384
 *  Parameters:
385
 *      Standard printf type parameters
386
 *
387
 *  Returns:
388
 *      TRUE : Operation was succesful
389
 *
390
 *========================================================================*/
391
 
392
int raw_print( const char *format, ... )
393
{
394
    va_list     ap;
395
    char        pp[200];
396
    int         len;
397
 
398
 
399
    va_start( ap, format );
400
    len = vsprintf( pp, format, ap );
401
    va_end( ap );
402
 
403
    fwrite( pp, 1, len, pfile );
404
 
405
    return ( len );
406
}
407
 
408
 
409
/*========================================================================
410
 *
411
 *  Control bolding
412
 *
413
 *  Purpose:
414
 *      This function is called to turn bolding on and off
415
 *      This function will ONLY affect HTML printing
416
 *
417
 *  Parameters:
418
 *      on              - TRUE
419
 *
420
 *  Returns:
421
 *      Nothing
422
 *
423
 *========================================================================*/
424
 
425
void print_bold( bool on )
426
{
427
    if ( print_html )
428
    {
429
        if ( on )
430
            raw_print( "<B>" );
431
        else
432
            raw_print( "</B>" );
433
    }
434
}
435
 
436
/*========================================================================
437
 *
438
 *  Control underline
439
 *
440
 *  Purpose:
441
 *      This function is called to turn underline on and off
442
 *      This function will ONLY affect HTML printing and Non-HTML printing
443
 *      But in a different manner
444
 *
445
 *  Parameters:
446
 *      on              - TRUE
447
 *
448
 *  Returns:
449
 *      Nothing
450
 *
451
 *========================================================================*/
452
 
453
void print_underline( bool on )
454
{
455
    if ( print_html )
456
    {
457
        /*
458
        **  For HTML printing underline is simple
459
        */
460
        if ( on )
461
        {
462
            raw_print( "<U>" );
463
            print_underline_start = 1;
464
        }
465
        else if ( print_underline_start > 0 )
466
        {
467
            raw_print( "</U>" );
468
            print_underline_start = 0;
469
        }
470
    }
471
    else
472
    {
473
        /*
474
        **  Non-HTML printing
475
        **  Store underline start and stop column
476
        */
477
        if ( on )
478
            print_underline_start = print_col;
479
        else if ( print_underline_start >= 0 )
480
            print_underline_end = print_col;
481
    }
482
}
483
 
484
/*========================================================================
485
 *
486
 *  Control colour - HTML printing only
487
 *
488
 *  Purpose:
489
 *      This function is called to change the background colour within
490
 *      HTML text
491
 *
492
 *  Parameters:
493
 *      colour      - Colour control string
494
 *                    or NULL to trun colour OFF
495
 *
496
 *
497
 *  Returns:
498
 *      Nothing
499
 *
500
 *========================================================================*/
501
 
502
void print_colour( long colour )
503
{
504
    if ( print_html )
505
    {
506
        if ( print_current_colour )
507
        {
508
            raw_print( "</SPAN>" );
509
            print_current_colour = 0L;
510
        }
511
 
512
        if ( colour )
513
        {
514
            print_current_colour = colour;
515
            raw_print( "<SPAN STYLE=\"background: #%6.6lx\">", colour );
516
        }
517
    }
518
}
519
 
520
 
521
/*========================================================================
522
 *
523
 *  Print a page banner
524
 *
525
 *  Purpose:
526
 *      This function is called to print a page banner
527
 *
528
 *  Parameters:
529
 *      None
530
 *
531
 *  Returns:
532
 *      Nothing
533
 *
534
 *========================================================================*/
535
 
536
void printbanner( const char *title )
537
{
538
    int         l, s;
539
 
540
    if ( !title )
541
        return;
542
 
543
    l = strlen( config.event_name );
544
    s = ( print_width - l ) / 2;
545
    print( "%*s", s, "" );
546
 
547
    if ( print_html == html )
548
        print( "<A HREF=\"%s\">", p_filename(filebase, "index" ,"html"));
549
    print_underline( TRUE);
550
    print_bold( TRUE );
551
 
552
    print( "%s", config.event_name );
553
 
554
    print_bold( FALSE );
555
    print_underline( FALSE );
556
    if ( print_html == html )
557
        print( "</A>" );
558
 
559
    print( "\n" );
560
 
561
    /*
562
    **  Print out one line with the report title
563
    **  on the left and the report time on the right
564
    */
565
    if ( title )
566
        print( "%s", title );
567
 
568
    s = print_width - print_col - 24 - 4;
569
    print( "%*s", s , "" );
570
 
571
    print( "%.24s", ctime( &pri_time ) );
572
    print( "\n" );
573
    print( "\n" );
574
}
575
 
576
 
577
/*========================================================================
578
 *
579
 *  Format a filename
580
 *
581
 *  Purpose:
582
 *      This function is called create a suitably formatted filename
583
 *      for use in an HTML tag or by the file system
584
 *
585
 *      Currently all output filenames are created in uppercase
586
 *      This is a limitation of DOS
587
 *      This function is used to ensure that all files are created with
588
 *      an uppercase name and that all HTML file references are also
589
 *      in uppercase.
590
 *
591
 *
592
 *  Parameters:
593
 *      filename        - Base filename
594
 *      Suffix          - Optional part of the basename
595
 *                        If present is used to create part of the basename
596
 *      ext             - Extension
597
 *
598
 *  Returns:
599
 *      Address of a static string that will reference the file
600
 *
601
 *========================================================================*/
602
 
603
char * p_filename( const char *filename, const char *suffix, const char *ext )
604
{
605
    char    *name;
606
    char    *cptr;
607
 
608
#ifndef LONG_FILE_NAMES
609
    /*
610
    **  Limit the filename to 8.3 format
611
    **  This is a limitation of the underlying file access library
612
    **  and may be removed in the future
613
    */
614
    if ( suffix[0] )
615
        name = tprintf ( "%.4s_%.3s.%.3s", filename, suffix, ext );
616
    else
617
        name = tprintf ( "%.8s.%.3s", filename, ext );
618
 
619
 
620
    /*
621
    **  Uppercase the filename
622
    */
623
    cptr = name;
624
    while ( *cptr )
625
    {
626
        *cptr = toupper( *cptr );
627
        cptr++;
628
    }
629
#else
630
    /*
631
    **  This compiler and runtime library supports
632
    **  long filenames - created printed filenames in lower case
633
    */
634
    if ( suffix[0] )
635
        name = tprintf ( "%s_%s.%s", filename, suffix, ext );
636
    else
637
        name = tprintf ( "%s_%s.%s", filename, ext, "txt" );
638
 
639
    cptr = name;
640
    while ( *cptr )
641
    {
642
        *cptr = tolower( *cptr );
643
        cptr++;
644
    }
645
#endif
646
 
647
    return( name );
648
}
649
 
650
 
651
/*========================================================================
652
 *
653
 *  Print to a temp string buffer
654
 *
655
 *  Purpose:
656
 *      This function is similar to sprintf() except that the routine
657
 *      maintains a list of string buffers and will return one to the
658
 *      user.
659
 *
660
 *      This function allows a user to create small, short lived
661
 *      printed strings, without the memory managment overhead.
662
 *
663
 *      Down-side. Use the string quickly.
664
 *                 Strings have a limited length
665
 *
666
 *  Parameters:
667
 *      Standard printf type parameters
668
 *
669
 *  Returns:
670
 *      TRUE : Operation was succesful
671
 *
672
 *========================================================================*/
673
 
674
#define TBUF_COUNT  5               /* Number of buffers */
675
#define TBUF_LENGTH 100             /* Max length of a single print */
676
 
677
char *tprintf( const char *format, ... )
678
{
679
    static char tbuf[TBUF_COUNT][TBUF_LENGTH];
680
    static int  index = 0;
681
 
682
    va_list     ap;
683
    char       *pp;
684
 
685
    /*
686
    **  Get the next entry from the small store
687
    */
688
    index++;
689
    if( index >= TBUF_COUNT )
690
        index = 0;
691
    pp = tbuf[index];
692
 
693
    va_start( ap, format );
694
    vsprintf( pp, format, ap );
695
    va_end( ap );
696
 
697
    return ( pp );
698
}
699
 
700
/*----------------------------------------------------------------------------
701
** FUNCTION           : to_hex
702
**
703
** DESCRIPTION        : Converts an integer value to its hex character
704
**
705
**
706
** INPUTS             : code        - Code to convert
707
**
708
** RETURNS            : Character representation
709
**
710
----------------------------------------------------------------------------*/
711
 
712
char to_hex(char code)
713
{
714
  static char hex[] = "0123456789abcdef";
715
  return hex[code & 0x0f];
716
}
717
 
718
/*----------------------------------------------------------------------------
719
** FUNCTION           : url_encode
720
**
721
** DESCRIPTION        : URL encoded version of a string
722
**
723
**
724
** INPUTS             : string to encode
725
**
726
** RETURNS            : Encoded string
727
**
728
** WARNING            : Uses a small circular pool of strings so that the
729
**                      user doesn't need to worry about string release
730
**
731
----------------------------------------------------------------------------*/
732
char *url_encode(const char *str)
733
{
734
    static char tbuf[TBUF_COUNT][TBUF_LENGTH * 3];
735
    static int  index = 0;
736
    char       *pp;
737
 
738
    /*
739
    **  Get the next entry from the small store
740
    */
741
    index++;
742
    if( index >= TBUF_COUNT )
743
        index = 0;
744
    pp = tbuf[index];
745
 
746
    const char *pstr = str;
747
    char *pbuf = pp;
748
 
749
    while (*pstr)
750
    {
751
        if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
752
            *pbuf++ = *pstr;
753
        else if (*pstr == ' ')
754
            *pbuf++ = '+';
755
        else
756
        {
757
            *pbuf++ = '%';
758
            *pbuf++ = to_hex(*pstr >> 4);
759
            *pbuf++ = to_hex(*pstr & 15);
760
        }
761
        pstr++;
762
    }
763
    *pbuf = '\0';
764
  return pp;
765
}
766
 
767
/********************************* EOF ***********************************/