Subversion Repositories svn1

Rev

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

Rev Author Line No. Line
91 - 1
/*************************************************************************
2
*           Copyright (C) 1995 Embedded Solutions
3
*                       All rights reserved
4
*
5
* file:     src\legtime.c
6
*
7
* purpose:  Leg time calculations
8
*
9
* functions
10
*   set_legs                    - Menu: Setup leg times
11
*   tm_lgs                      - Set up the leg start times for leg
12
*   leg_start                   - Set up the leg start times
13
*   tm_fixedstart               - Set the start time for a specific leg
14
*   tm_staggered                - Set a staggered start time for a specific leg
15
*   tm_clearleg                 - Clear start times on a specific leg
16
*   leg_ini                     - Initialize all stored times
17
*   tm_init                     - Initialize all team data
18
*   tm_gen                      - Generate dummy team names
19
*   legs_start_report           - Generate starters report
20
*   ls_timer                    - print the current leg entry
21
*   ls_team                     - print next ( numeric ) leg entry
22
*   sort_legs                   - Qsort callback function
23
*
24
* programmer: David Purdie
25
*
26
* revision  date        by      reason
27
*           11-Oct-89   DDP     leg-3 starttime. Now has an option to generate
28
*                               a printed report of teams and times
29
*
30
*           21-May-90   MV      now able to set start time and generate
31
*                               a printed report for any leg
32
*   00.0    27/01/95    DDP     Tidies up the program and formatted the file
33
*
34
**************************************************************************/
35
 
36
#include    "consts.h"
37
#include    "structs.h"
38
#include    "proto.h"
39
 
40
#if defined(HI_TECH_C) || defined(__TURBOC__)
41
#include    <alloc.h>
42
#endif
43
 
44
menu_table  leg_menu[] = {
45
    { '1', "Set start time from category", leg_start },
46
    { '2', "Clear all leg times", leg_ini },
47
    { '3', "Reset team information", tm_init },
48
    { '4', "Generate dummy team names", tm_gen },
130 - 49
    //{ '5', "Set calculated leg start", tm_lgs },
131 david 50
    //{ '6', "Set ordered incremental leg start", tm_lgs1 },
51
    //{ '7', "Set staggered start time", tm_staggered },
52
    //{ '8', "Set fixed start time", tm_fixedstart },
91 - 53
    { '9', "Clear single leg start times", tm_clearleg },
54
    { 'q', "Return to main menu", 0 },
55
    { '\0' }
56
};
57
 
58
/*========================================================================
59
 *
60
 *  Menu: Setup leg times
61
 *
62
 *  Purpose:
63
 *      This function is called to produce the menu that will
64
 *      setup leg times
65
 *
66
 *  Parameters:
67
 *      None
68
 *
69
 *  Returns:
70
 *      Nothing
71
 *
72
 *========================================================================*/
73
 
74
void set_legs(void)
75
{
76
    do_menu( "Leg time setup", "Select option", leg_menu );
77
}
78
 
79
/*========================================================================
80
 *
81
 *  Set up the leg start times for leg
82
 *
83
 *  Purpose:
84
 *      This function is called to Set up the leg start times for leg
85
 *      The start time is based on category information
86
 *
87
 *  Parameters:
88
 *      None
89
 *
90
 *  Returns:
91
 *      Nothing
92
 *
93
 *========================================================================*/
94
 
131 david 95
void tm_lgs1(int leg, time_t starttime, time_t delta, bool report_it, bool clear_it)
91 - 96
{
97
    t_legs     *data;                            /* Address of table */
98
    t_legs     *dptr;                            /* Moving pointer */
99
    int         num_records;                     /* Number of records in array */
100
    int         i;
101
 
102
 
103
    /*
104
    **  Read existing data into memory
105
    */
106
    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */
107
    if( !data )
108
    {
109
        printf( "\nNo memory for report\n" );
110
        return;
111
    }
112
 
113
    /*
114
     * Extract the required data from the data base
115
     * Only save that information required for the operation
116
     *      - The end time of the previous leg
117
     */
118
    dptr = data;
119
    num_records = 0;
120
    for( i = config.min_team; i <= config.max_team; i++ )
121
    {
122
        if( valid_field( i ) && g_record( i, &team_buf ) )
123
        {
124
            dptr->numb = team_buf.numb;
125
            dptr->start = team_buf.leg[leg-1].end;
126
            dptr->flags = team_buf.flags;
127
            dptr++;
128
            num_records++;
129
        }
130
    }
131
 
132
    /*
133
     * Sort the data into some logical order 
134
     */
135
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );
136
 
137
    /*
138
    **  Update the team information based on the start order
139
    **  Ignore validity flags as the data will have been sorted with
140
    **  these in mind.
141
    */
142
    for( dptr = data, i = 0; i < num_records; i++, dptr++ )
143
    {
144
        if( valid_field( dptr->numb ) )
145
        {
146
            g_record( dptr->numb, &team_buf );
147
            team_buf.leg[leg].start = starttime;
148
            starttime += delta;
149
            team_buf.leg[leg].manual = TRUE;
150
 
151
            set_times( &team_buf );
152
            test_times( &team_buf, 0 );
153
            put_team_record( dptr->numb, &team_buf );
154
        }
155
 
156
        if( i % 10 == 0 )
157
        {
158
            cur( 0, 8 );
159
            printf( "Upto entry %d", i );
160
            flush_out();
161
        }
162
    }
163
 
164
    /*
165
    **  Release the data
166
    */
167
    free( data );
168
 
169
    if( report_it )
131 david 170
        legs_start_report(9, leg);
91 - 171
 
172
    if ( clear_it )
173
        tm_clearleg_specified( leg, TRUE, 10 );
174
}
175
 
176
/*========================================================================
177
 *
178
 *  Set up the leg start times for leg
179
 *
180
 *  Purpose:
181
 *      This function is called to Set up the leg start times for leg
182
 *      The start time is based on current placing with:
183
 *          A constant offset added ( ie: lunch)
184
 *          A fixed increment
185
 *
186
 *  Parameters:
187
 *      None
188
 *
189
 *  Returns:
190
 *      Nothing
191
 *
192
 *========================================================================*/
193
 
130 - 194
void tm_lgs(int leg, time_t delta, bool report_it, bool clear_it)
91 - 195
{
196
 
197
    team = config.min_team;                      /* Team we are working with */
198
    while( team <= config.max_team )
199
    {
200
        if( valid_field( team ) )
201
        {
202
            g_record( team, &team_buf );
203
            if( team_buf.flags.valid && team_buf.leg[leg - 1].end > 0 )
204
            {
205
                team_buf.leg[leg].start = team_buf.leg[leg - 1].end + delta;
206
                team_buf.leg[leg].manual = TRUE;
207
            }
208
            else
209
                team_buf.leg[leg].start = ( time_t ) - 1;
210
 
211
            set_times( &team_buf );
212
            test_times( &team_buf, 0 );
213
            put_team_record( team, &team_buf );
214
        }
215
 
216
        if( team % 10 == 0 )
217
        {
130 - 218
 
91 - 219
            printf( "Upto team %d", team );
220
            flush_out();
221
        }
222
        team++;
223
    }
224
 
225
    if( report_it )
131 david 226
        legs_start_report(0, leg);
91 - 227
 
228
    if ( clear_it )
130 - 229
        tm_clearleg_specified( leg, TRUE, 0 );
91 - 230
}
231
 
232
/*========================================================================
233
 *
234
 *  Set up the leg start times
235
 *
236
 *  Purpose:
237
 *      This function is called to Set up the leg start times
238
 *
239
 *  Parameters:
240
 *      None
241
 *
242
 *  Returns:
243
 *      Nothing
244
 *
245
 *========================================================================*/
246
 
247
void leg_start(void)
248
{
249
 
250
    team = config.min_team;                      /* Team we are working with */
126 david 251
//    cur( 0, 5 );
252
//    printf( "Setting start times for all valid teams from %-d to %-d \n",
253
//            config.min_team, config.max_team );
254
//    if( !getyes( "Continue operation" ) )
255
//        return;
91 - 256
 
257
    while( team <= config.max_team )
258
    {
259
        if( valid_field( team ) )
260
        {
261
            ( void ) g_record( team, &team_buf );
262
            if( team_buf.teamclass > 0 && team_buf.teamclass <= config.num_class )
263
                team_buf.leg[0].start =
264
                    config.team_class[team_buf.teamclass - 1].start;
265
            else
266
                team_buf.leg[0].start = ( time_t ) - 1;
267
            team_buf.leg[1].manual = 0;
268
            team_buf.leg[1].start = team_buf.leg[0].start;
269
            team_buf.leg[0].l_place = 0;
270
            team_buf.leg[0].le_place = 0;
271
            team_buf.leg[0].lec_place = 0;
272
            team_buf.leg[0].lc_place = 0;
273
            team_buf.leg[0].manual = FALSE;
274
            set_times( &team_buf );
275
            test_times( &team_buf, 0 );
276
            put_team_record( team, &team_buf );
277
        }
278
        if( team % 10 == 0 )
279
        {
280
            cur( 0, 8 );
281
            printf( "Upto team %d", team );
282
            flush_out();
283
        }
284
        team++;
285
    }
286
}
287
 
288
/*========================================================================
289
 *
290
 *  Set the start time for a specific leg
291
 *
292
 *  Purpose:
293
 *      This function is called to set the start time for a specific
294
 *      leg to a specified and fixed time
295
 *
296
 *  Parameters:
297
 *      None
298
 *
299
 *  Returns:
300
 *      Nothing
301
 *
302
 *========================================================================*/
303
 
131 david 304
void tm_fixedstart(int leg, time_t starttime, bool report_it, bool clear_it)
91 - 305
{
306
    int         line = 5;                        /* Current line */
307
 
308
    while( team <= config.max_team )
309
    {
310
        if( valid_field( team ) )
311
        {
312
            g_record( team, &team_buf );
313
            if( team_buf.flags.valid )
314
            {
315
                team_buf.leg[leg].start = starttime;
316
                team_buf.leg[leg].manual = TRUE;
317
            }
318
            else
319
                team_buf.leg[leg].start = ( time_t ) - 1;
320
 
321
            set_times( &team_buf );
322
            test_times( &team_buf, 0 );
323
            put_team_record( team, &team_buf );
324
        }
325
 
326
        if( team % 10 == 0 )
327
        {
328
            cur( 0, 8 );
329
            printf( "Upto team %d", team );
330
            flush_out();
331
        }
332
        team++;
333
    }
334
 
335
    if( report_it )
131 david 336
        legs_start_report(++line, leg);
91 - 337
 
338
    if ( clear_it )
339
        tm_clearleg_specified( leg, TRUE, ++line );
340
}
341
 
342
/*========================================================================
343
 *
344
 *  Set a staggered start time for a specific leg
345
 *
346
 *  Purpose:
347
 *      This function is called to set the start time for a specific
348
 *      leg to a specified and a staggered time
349
 *
350
 *  Parameters:
351
 *      None
352
 *
353
 *  Returns:
354
 *      Nothing
355
 *
356
 *========================================================================*/
357
 
131 david 358
void tm_staggered(int leg, time_t starttime, time_t delta, bool report_it, bool clear_it )
91 - 359
{
360
    int         line = 5;                        /* Current line */
361
 
362
    while( team <= config.max_team )
363
    {
364
        if( valid_field( team ) )
365
        {
366
            g_record( team, &team_buf );
367
            if( team_buf.flags.valid )
368
            {
369
                team_buf.leg[leg].start = starttime;
370
                starttime += delta;
371
                team_buf.leg[leg].manual = TRUE;
372
            }
373
            else
374
                team_buf.leg[leg].start = ( time_t ) - 1;
375
 
376
            set_times( &team_buf );
377
            test_times( &team_buf, 0 );
378
            put_team_record( team, &team_buf );
379
        }
380
 
381
        if( team % 10 == 0 )
382
        {
383
            cur( 0, 9 );
384
            printf( "Upto team %d", team );
385
            flush_out();
386
        }
387
        team++;
388
    }
389
 
390
    if( report_it )
131 david 391
        legs_start_report(++line, leg);
91 - 392
 
393
    if ( clear_it )
394
        tm_clearleg_specified( leg, TRUE,  ++line );
395
}
396
 
397
/*========================================================================
398
 *
399
 *  Clear start times on a specific leg
400
 *
401
 *  Purpose:
402
 *      This function is called to clear start times on a specifc leg
403
 *
404
 *  Parameters:
405
 *      None
406
 *
407
 *  Returns:
408
 *      Nothing
409
 *
410
 *========================================================================*/
411
 
412
void tm_clearleg(void)
413
{
414
 
415
    cur( 0, 5 );
416
    while( TRUE )
417
    {
418
        leg = 0;
419
        d_field( 0, 5, "Enter leg to clear start time :", D_NUMBER, 1,
420
                 ( char * ) &leg, TRUE, M_UPDATE );
421
        if( leg == 0 )
422
            return;                              /* Null leg - just exit */
423
        if( leg <= config.num_legs )             /* Valid leg number - Exit loop */
424
            break;
425
        beep();                                /* Make a noise and wait for valid number */
426
    }
427
 
428
 
429
    cur( 0, 5 );
430
    printf
431
        ( "Setting start times for all valid teams from %-d to %-d for leg %d\n",
432
          config.min_team, config.max_team, leg );
433
    if( !getyes( "Continue operation" ) )
434
        return;
435
 
436
    tm_clearleg_specified( leg, FALSE, 6 );
437
}
438
 
439
/*========================================================================
440
 *
441
 *  Clear start times on a specific leg
442
 *
443
 *  Purpose:
444
 *      This function is called to clear start times on a specifc leg
445
 *
446
 *  Parameters:
447
 *      cleg                - Leg to clear
448
 *      manual              - Force manual, else leave alone
449
 *      line                - Current display line number
450
 *
451
 *  Returns:
452
 *      Nothing
453
 *
454
 *========================================================================*/
455
 
456
void tm_clearleg_specified(int cleg, bool manual, int line)
457
{
458
 
459
    /*
460
    **  Validate the users argument
461
    */
462
    if( cleg == 0 )
463
        return;                              /* Null leg - just exit */
464
    if( cleg > config.num_legs )             /* Valid leg number - Exit loop */
465
        return;
466
    leg = cleg;
467
 
468
    team = config.min_team;                 /* Team we are working with */
469
    while( team <= config.max_team )
470
    {
471
        if( valid_field( team ) )
472
        {
473
            g_record( team, &team_buf );
474
            team_buf.leg[leg].manual = manual;
475
            team_buf.leg[leg].start = ( time_t ) -1;
476
 
477
            set_times( &team_buf );
478
            test_times( &team_buf, 0 );
479
            put_team_record( team, &team_buf );
480
        }
481
        if( team % 10 == 0 )
482
        {
483
            cur( 0, line );
484
            printf( "Upto team %d", team );
485
            flush_out();
486
        }
487
        team++;
488
    }
489
}
490
 
491
 
492
/*========================================================================
493
 *
494
 *  Initialize all stored times
495
 *
496
 *  Purpose:
497
 *      This function is called to Initialize all stored times
498
 *
499
 *  Parameters:
500
 *      None
501
 *
502
 *  Returns:
503
 *      Nothing
504
 *
505
 *========================================================================*/
506
 
507
void leg_ini(void)
508
{
509
    int         i;
510
 
511
 
512
    team = config.min_team;                      /* Team we are working with */
513
    while( team <= config.max_team )
514
    {
515
        if( valid_field( team ) )
516
        {
517
            ( void ) g_record( team, &team_buf );
518
            for( i = 0; i <= MAX_LEGS; i++ )
519
            {
520
                team_buf.leg[i].start = team_buf.leg[i].end =
521
                    team_buf.leg[i].elapsed = ( time_t ) - 1;
522
                team_buf.leg[i].l_place = 0;
523
                team_buf.leg[i].le_place = 0;
524
                team_buf.leg[i].lec_place = 0;
525
                team_buf.leg[i].lc_place = 0;
526
                team_buf.leg[i].manual = FALSE;
527
            }
528
            if( team_buf.teamclass > 0 && team_buf.teamclass <= config.num_class )
529
                team_buf.leg[0].start =
530
                    config.team_class[team_buf.teamclass - 1].start;
531
            else
532
                team_buf.leg[0].start = ( time_t ) - 1;
533
 
534
            team_buf.leg[1].start = team_buf.leg[0].start;
535
            team_buf.flags.disqualified = FALSE;
536
            team_buf.flags.non_equestrian = FALSE;
537
            put_team_record( team, &team_buf );
538
        }
539
        if( team % 10 == 0 )
540
        {
541
            cur( 0, 8 );
542
            printf( "Upto team %d", team );
543
            flush_out();
544
        }
545
        team++;
546
    }
547
}
548
 
549
/*========================================================================
550
 *
551
 *  Initialize all team data
552
 *
553
 *  Purpose:
554
 *      This function is called to Initialize all team data
555
 *
556
 *  Parameters:
557
 *      None
558
 *
559
 *  Returns:
560
 *      Nothing
561
 *
562
 *========================================================================*/
563
void tm_init(void)
564
{
565
 
566
    team = config.min_team;                      /* Team we are working with */
567
    while( team <= config.max_team )
568
    {
569
        if( valid_field( team ) )
570
        {
571
            clr_team( team, &team_buf );
572
            put_team_record( team, &team_buf );
573
        }
574
        if( team % 10 == 0 )
575
        {
576
            cur( 0, 8 );
577
            printf( "Upto team %d", team );
578
            flush_out();
579
        }
580
        team++;
581
    }
582
}
583
 
584
/*========================================================================
585
 *
586
 *  Generate dummy team names
587
 *
588
 *  Purpose:
589
 *      This function is called to Generate dummy team names
590
 *
591
 *  Parameters:
592
 *      None
593
 *
594
 *  Returns:
595
 *      Nothing
596
 *
597
 *========================================================================*/
598
 
599
void tm_gen(void)
600
{
601
 
602
    team = config.min_team;                      /* Team we are working with */
603
    while( team <= config.max_team )
604
    {
605
        if( valid_field( team ) )
606
        {
607
            ( void ) g_record( team, &team_buf );
608
            team_buf.flags.valid = TRUE;
609
            sprintf( team_buf.name, "Team - %4.4d", team );
610
            team_buf.teamclass = 1;                  /* Set default class */
611
            put_team_record( team, &team_buf );
612
        }
613
        if( team % 10 == 0 )
614
        {
615
            cur( 0, 8 );
616
            printf( "Upto team %d", team );
617
            flush_out();
618
        }
619
        team++;
620
    }
621
}
622
 
623
 
624
/*========================================================================
625
 *
626
 *  Generate starters report
627
 *
628
 *  Purpose:
629
 *      This routine is used to generate a list of leg start times
630
 *      This system can cope with a break at the start of leg
631
 *
632
 *  Parameters:
633
 *      None
634
 *
635
 *  Returns:
636
 *      Nothing
637
 *
638
 *========================================================================*/
639
 
131 david 640
void legs_start_report(int line, int leg)
91 - 641
{
642
    int         i;
643
    t_legs     *data;                            /* Address of table */
644
    t_legs     *dptr;                            /* Moving pointer */
645
    int         last_team;
646
    int         num_records = 0;                 /* Number of records in array */
647
    char        l_s[40];                         /* Name of start time file */
648
 
649
    cur( 0, line );
650
    printf( "Generating Starters report for Leg-%d", leg );
651
 
652
    data = ( t_legs * ) calloc( ( unsigned ) ( config.max_team - config.min_team + 2 ), sizeof( t_legs ) ); /* Fetch memory */
653
 
654
    if( !data )
655
    {
656
        printf( "\nNo memory for report\n" );
657
        return;
658
    }
659
 
660
    /*
661
     * Extract the required data from the data base
662
     * Only save that information required for the operation
663
     */
664
 
665
    dptr = data;
666
    for( i = config.min_team; i <= config.max_team; i++ )   /* Print team order data */
667
    {
668
        if( valid_field( i ) && g_record( i, &team_buf ) )
669
        {
670
            dptr->numb = team_buf.numb;
671
            dptr->start = team_buf.leg[leg].start;
672
            dptr->flags = team_buf.flags;
673
            dptr++;
674
            num_records++;
675
        }
676
    }
677
 
678
 
679
    /*
680
     * Sort the data into some logical order 
681
     */
682
    qsort( ( char * ) data, num_records, sizeof( t_legs ), sort_legs );
683
 
684
    /*
685
    **  Now print the data on the printer
686
    **      - Generte the name of the printer file
687
    **      - Open the printer
688
    */
689
 
690
    sprintf( l_s, "l_%d", leg );
691
    if( !open_printer( "", l_s, 80, text, "Starters Report" ) )
692
        return;
693
 
694
    /*
695
     * Print out the header for the file 
696
     */
697
    print( "\nStarters report for leg:%d %-*s\n", leg, 18, config.leg_name[leg - 1] );
698
    print( "Team order listing\n\n" );
699
 
700
    print_underline (TRUE);
701
    print( "%-8s   %-5s   %-8s   |   %-5s   %-8s", "Time", "Team", "DeltaT", "Team", "Time" );
702
    print_underline (FALSE);
703
    print( "\n" );
704
 
705
    last_team = 0;
706
    for( dptr = data, i = 0; i < num_records; i++ )
707
    {
708
        ls_timer( dptr++, i );
709
        print( "   |   " );
710
        ls_team( &last_team, data );
711
        print( "\n" );
712
    }
713
 
714
    print( "\nTeams without marked times will be started when ALL marked teams\n" );
715
    print( "have been started.\n" );
716
 
717
    /*
718
    **  Release the resources
719
    **      - Printer
720
    **      - Memory
721
    */
722
    close_printer();
723
    free( data );
724
}
725
 
726
/*========================================================================
727
 *
728
 *  print the current leg entry
729
 *
730
 *  Purpose:
731
 *      This function is a helper routine to print the current leg entry
732
 *      in time : Team number order
733
 *
734
 *  Parameters:
735
 *      ptr     Pointer to entry
736
 *      num     Entry index
737
 *
738
 *  Returns:
739
 *      Nothing
740
 *
741
 *========================================================================*/
742
 
743
void ls_timer( t_legs * ptr, int num )
744
{
745
    time_t      time;
746
    time_t      delta;
747
 
748
    if( num == 0 )
749
        delta = ( time_t ) - 1;
750
    else
751
        delta = ptr[0].start - ptr[-1].start;
752
 
753
    time = ptr->start;
754
    if( ptr->flags.disqualified )
755
        time = ( time_t ) - 1;
756
 
757
    print( "%-8s   %-5d", time_fa( time, ptr->flags.disqualified ),
758
           ptr->numb );
759
    print( "   %-8s", time_fa( delta, TRUE ) );
760
}
761
 
762
 
763
/*========================================================================
764
 *
765
 *  print next ( numeric ) leg entry
766
 *
767
 *  Purpose:
768
 *      This helper function is called to print next ( numeric ) leg entry
769
 *      in Team # time order
770
 *
771
 *  Parameters:
772
 *      last        Last one found
773
 *                  Used to relocate my self
774
 *      data        Start of data
775
 *
776
 *  Returns:
777
 *      Nothing
778
 *
779
 *========================================================================*/
780
 
781
void ls_team( int *last, t_legs * data )
782
{
783
    t_legs     *min;
784
    time_t      time;
785
 
786
    for( min = 0; data->numb; data++ )
787
    {
788
        if( data->numb > *last && ( min == 0 || data->numb < min->numb ) )
789
            min = data;
790
    }
791
    *last = min->numb;                           /* Save current team as done */
792
 
793
    time = min->start;
794
    if( min->flags.disqualified )
795
        time = ( time_t ) - 1;
796
    print( "%-5d   %-8s", min->numb,
797
           time_fa( time, min->flags.disqualified ) );
798
}
799
 
800
/*========================================================================
801
 *
802
 *  Qsort callback function
803
 *
804
 *  Purpose:
805
 *      This function is provided to Qsort() to sort the teams
806
 *
807
 *  Parameters:
808
 *      a           - Leg entry to compare
809
 *      b           - Leg entry to compare
810
 *
811
 *
812
 *  Returns:
813
 *      -1      a < b
814
 *       0      a = b
815
 *       1      a > b
816
 *
817
 *========================================================================*/
818
 
819
int sort_legs( const void * aa, const void * bb )
820
{
821
 
822
    const t_legs * a = (const t_legs *)aa;
823
    const t_legs * b = (const t_legs *)bb;
824
 
825
    int         a_bad;
826
    int         b_bad;
827
 
828
    a_bad = a->flags.disqualified || a->start <= 0;
829
    b_bad = b->flags.disqualified || b->start <= 0;
830
 
831
    if( a_bad || b_bad )                         /* Valid data has precedence */
832
    {
833
        if( a_bad && b_bad )
834
            return ( a->numb - b->numb );
835
        else
836
            return ( a_bad ? 1 : -1 );
837
    }
838
 
839
    if( a->start == b->start )
840
        return ( a->numb - b->numb );
841
    else
842
    {
843
        if( ( a->start > 0 ) && ( b->start > 0 ) )
844
            return ( ( int ) ( a->start - b->start ) );
845
        else
846
            return ( ( a->start > 0 ) ? -1 : 1 );
847
    }
848
}
849
 
850
/********************************* EOF ***********************************/