Subversion Repositories svn1-original

Rev

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