]> git.sur5r.net Git - cc65/blob - test/val/cq81.c
remote TABs in doc/ and test/
[cc65] / test / val / cq81.c
1 /*
2   !!DESCRIPTION!! C-Manual Chapter 8.1: storage class specifiers
3   !!ORIGIN!!      LCC 4.1 Testsuite
4   !!LICENCE!!     own, freely distributeable for non-profit. read CPYRIGHT.LCC
5 */
6
7 #include "common.h"
8
9 struct defs {
10      int cbits;          /* No. of bits per char           */
11      int ibits;          /*                 int            */
12      int sbits;          /*                 short          */
13      int lbits;          /*                 long           */
14      int ubits;          /*                 unsigned       */
15      int fbits;          /*                 float          */
16      int dbits;          /*                 double         */
17      #ifndef NO_FLOATS
18         float fprec;        /* Smallest number that can be    */
19         float dprec;        /* significantly added to 1.      */
20      #endif
21      int flgs;           /* Print return codes, by section */
22      int flgm;           /* Announce machine dependencies  */
23      int flgd;           /* give explicit diagnostics      */
24      int flgl;           /* Report local return codes.     */
25      int rrc;            /* recent return code             */
26      int crc;            /* Cumulative return code         */
27      char rfs[8];        /* Return from section            */
28 };
29
30      int lbits;          /*                 long           */
31      int ubits;          /*                 unsigned       */
32      int fbits;          /*                 float          */
33      int dbits;          /*                 double         */
34      #ifndef NO_FLOATS
35         float fprec;        /* Smallest number that can be    */
36         float dprec;        /* significantly added to 1.      */
37      #endif
38      int flgs;           /* Print return codes, by section */
39      int flgm;           /* Announce machine dependencies  */
40      int flgd;           /* give explicit diagnostics      */
41      int flgl;           /* Report local return codes.     */
42      int rrc;            /* recent return code             */
43      int crc;            /* Cumulative return code         */
44      char rfs[8];        /* Return from section            */
45
46 #ifdef NO_IMPLICIT_FUNC_PROTOTYPES
47 regc();
48 regp();
49 regi();
50 #endif
51
52 #ifndef NO_OLD_FUNC_DECL
53 s81(pd0)              /* 8.1 Storage Class Specifiers    */
54 struct defs *pd0;
55 #else
56 int s81(struct defs *pd0)
57 #endif
58 {
59    static char s81er[] = "s81,er%d\n";
60    static char qs81[8] = "s81    ";
61    char *ps, *pt;
62    int k, rc, j, crc, prc, irc;
63    register char rchar;
64             char nrchar;
65    register int *rptr;
66             int *nrptr;
67    register int rint;
68             int nrint;
69    static char badtest[] = "Register count for %s is unreliable.\n";
70    static char goodtest[] = "%d registers assigned to %s variables.\n";
71
72    rc = 0;
73    crc = 0;
74    prc = 0;
75    irc = 0;
76    ps = qs81;
77    pt = pd0->rfs;
78
79    while(*pt++ = *ps++);
80
81 /*    The storage class specifiers are:
82
83         auto
84         static
85         extern
86         register
87         typedef
88
89       The first three of these were treated earlier, in s4. The last
90    will be checked in s88. "Register" remains.
91
92       There are three flavors of register, viz., char, int and pointer.
93    We wish first to ascertain that the representations as register
94    are consistent with the corresponding nonregister representations.
95                                                                  */
96
97    k = 1;
98    for (j=0; j<50; j++){
99      rchar = k;
100      nrchar = k;
101      rptr = &k;
102      nrptr = &k;
103      rint = k;
104      nrint = k;
105
106      if ( rchar != nrchar ) crc = 1;
107      if ( rptr != nrptr ) prc = 1;
108      if ( rint != nrint ) irc = 1;
109      k = k<<1;
110    }
111
112    if ( crc != 0 ) {
113      rc = rc+1;
114      if( pd0 -> flgd != 0 ) printf(s81er,1);
115    }
116
117    if ( prc != 0 ) {
118      rc = rc+2;
119      if( pd0 -> flgd != 0 ) printf(s81er,2);
120    }
121
122    if ( irc != 0 ) {
123      rc = rc+4;
124      if( pd0 -> flgd != 0 ) printf(s81er,4);
125    }
126
127 /*   Now we check to see if variables are actually being assigned
128      to registers.                       */
129
130    k = regc();
131    if ( pd0->flgm != 0 ) {
132      if ( k < 0 ) printf(badtest,"char");
133      else printf(goodtest,k,"char");
134    }
135
136    k = regp();
137    if ( pd0->flgm != 0 ) {
138      if ( k<0 ) printf(badtest,"pointer");
139      else printf(goodtest,k,"pointer");
140    }
141
142    k = regi();
143    if ( pd0->flgm != 0 ) {
144      if ( k<0 ) printf(badtest,"int");
145      else printf(goodtest,k,"int");
146    }
147
148    return rc;
149 }
150 regc() {     /*   char to register assignment   */
151 /*   Testing a variable whose storage class has been spec-
152 ified as "register" is somewhat tricky, but it can be done in a
153 fairly reliable fashion by taking advantage of our knowledge of the
154 ways in which compilers operate. If we declare a collection of vari-
155 ables of the same storage class, we would expect that, when storage
156 for these variables is actually allocated, the variables will be
157 bunched together and ordered according to one of the following
158 criteria:
159
160      (a) the order in which they were defined.
161      (b) the order in which they are used.
162      (c) alphabetically.
163      (d) the order in which they appear in the compiler's
164          symbol table.
165      (e) some other way.
166
167      Hence, if we define a sequence of variables in close alpha-
168 betical order, and use them in the same order in which we define
169 them, we would expect the differences between the addresses of
170 successive variables to be constant, except in case (d) where the
171 symbol table is a hash table, or in case (e). If a subsequence in
172 the middle of this sequence is selected, and for this subsequence,
173 every other variable is specified to be "register", and address
174 differences are taken between adjacent nonregister variables, we would
175 still expect to find constant differences if the "register" vari-
176 ables were actually assigned to registers, and some other diff-
177 erences if they were not. Specifically, if we had N variables
178 specified as "register" of which the first n were actually ass-
179 igned to registers, we would expect the sequence of differences
180 to consist of a number of occurrences of some number, followed by
181 N-n occurrences of some other number, followed by several occurr-
182 ences of the first number. If we get a sequence like this, we can
183 determine, by simple subtraction, how many (if any) variables are
184 being assigned to registers. If we get some other sequence, we know
185 that the test is invalid.                                     */
186
187             char r00;
188             char r01;
189             char r02;
190             char r03;
191    register char r04;
192             char r05;
193    register char r06;
194             char r07;
195    register char r08;
196             char r09;
197    register char r10;
198             char r11;
199    register char r12;
200             char r13;
201    register char r14;
202             char r15;
203    register char r16;
204             char r17;
205    register char r18;
206             char r19;
207    register char r20;
208             char r21;
209    register char r22;
210             char r23;
211    register char r24;
212             char r25;
213    register char r26;
214             char r27;
215    register char r28;
216             char r29;
217    register char r30;
218             char r31;
219    register char r32;
220             char r33;
221    register char r34;
222             char r35;
223             char r36;
224             char r37;
225             char r38;
226
227    int s, n1, n2, nr, j, d[22];
228    r00 = 0;
229    r01 = 1;
230    r02 = 2;
231    r03 = 3;
232    r04 = 4;
233    r05 = 5;
234    r06 = 6;
235    r07 = 7;
236    r08 = 8;
237    r09 = 9;
238    r10 = 10;
239    r11 = 11;
240    r12 = 12;
241    r13 = 13;
242    r14 = 14;
243    r15 = 15;
244    r16 = 16;
245    r17 = 17;
246    r18 = 18;
247    r19 = 19;
248    r20 = 20;
249    r21 = 21;
250    r22 = 22;
251    r23 = 23;
252    r24 = 24;
253    r25 = 25;
254    r26 = 26;
255    r27 = 27;
256    r28 = 28;
257    r29 = 29;
258    r30 = 30;
259    r31 = 31;
260    r32 = 32;
261    r33 = 33;
262    r34 = 34;
263    r35 = 35;
264    r36 = 36;
265    r37 = 37;
266    r38 = 38;
267
268    d[0] = &r01 - &r00;
269    d[1] = &r02 - &r01;
270    d[2] = &r03 - &r02;
271    d[3] = &r05 - &r03;
272    d[4] = &r07 - &r05;
273    d[5] = &r09 - &r07;
274    d[6] = &r11 - &r09;
275    d[7] = &r13 - &r11;
276    d[8] = &r15 - &r13;
277    d[9] = &r17 - &r15;
278    d[10] = &r19 - &r17;
279    d[11] = &r21 - &r19;
280    d[12] = &r23 - &r21;
281    d[13] = &r25 - &r23;
282    d[14] = &r27 - &r25;
283    d[15] = &r29 - &r27;
284    d[16] = &r31 - &r29;
285    d[17] = &r33 - &r31;
286    d[18] = &r35 - &r33;
287    d[19] = &r36 - &r35;
288    d[20] = &r37 - &r36;
289    d[21] = &r38 - &r37;
290
291 /*   The following FSM analyzes the string of differences. It accepts
292 strings of the form a+b+a+ and returns 16 minus the number of bs,
293 which is the number of variables that actually got into registers.
294 Otherwise it signals rejection by returning -1., indicating that the
295 test is unreliable.              */
296
297    n1 = d[0];
298    s = 1;
299
300    for (j=0; j<22; j++)
301      switch (s) {
302        case 1: if (d[j] != n1) {
303                 n2 = d[j];
304                 s = 2;
305                 nr = 1;
306                }
307                break;
308        case 2: if (d[j] == n1) {
309                 s = 3;
310                 break;
311                }
312                if (d[j] == n2) {
313                 nr = nr+1;
314                 break;
315                }
316                s = 4;
317                break;
318        case 3: if (d[j] != n1) s = 4;
319                break;
320      }
321    ;
322
323    if (s == 3) return 16-nr;
324    else return -1;
325 }
326 regi() {     /*   int to register assignment    */
327 /*   Testing a variable whose storage class has been spec-
328 ified as "register" is somewhat tricky, but it can be done in a
329 fairly reliable fashion by taking advantage of our knowledge of the
330 ways in which compilers operate. If we declare a collection of vari-
331 ables of the same storage class, we would expect that, when storage
332 for these variables is actually allocated, the variables will be
333 bunched together and ordered according to one of the following
334 criteria:
335
336      (a) the order in which they were defined.
337      (b) the order in which they are used.
338      (c) alphabetically.
339      (d) the order in which they appear in the compiler's
340          symbol table.
341      (e) some other way.
342
343      Hence, if we define a sequence of variables in close alpha-
344 betical order, and use them in the same order in which we define
345 them, we would expect the differences between the addresses of
346 successive variables to be constant, except in case (d) where the
347 symbol table is a hash table, or in case (e). If a subsequence in
348 the middle of this sequence is selected, and for this subsequence,
349 every other variable is specified to be "register", and address
350 differences are taken between adjacent nonregister variables, we would
351 still expect to find constant differences if the "register" vari-
352 ables were actually assigned to registers, and some other diff-
353 erences if they were not. Specifically, if we had N variables
354 specified as "register" of which the first n were actually ass-
355 igned to registers, we would expect the sequence of differences
356 to consist of a number of occurrences of some number, followed by
357 N-n occurrences of some other number, followed by several occurr-
358 ences of the first number. If we get a sequence like this, we can
359 determine, by simple subtraction, how many (if any) variables are
360 being assigned to registers. If we get some other sequence, we know
361 that the test is invalid.                                     */
362
363             int r00;
364             int r01;
365             int r02;
366             int r03;
367    register int r04;
368             int r05;
369    register int r06;
370             int r07;
371    register int r08;
372             int r09;
373    register int r10;
374             int r11;
375    register int r12;
376             int r13;
377    register int r14;
378             int r15;
379    register int r16;
380             int r17;
381    register int r18;
382             int r19;
383    register int r20;
384             int r21;
385    register int r22;
386             int r23;
387    register int r24;
388             int r25;
389    register int r26;
390             int r27;
391    register int r28;
392             int r29;
393    register int r30;
394             int r31;
395    register int r32;
396             int r33;
397    register int r34;
398             int r35;
399             int r36;
400             int r37;
401             int r38;
402
403    int s, n1, n2, nr, j, d[22];
404
405    r00 = 0;
406    r01 = 1;
407    r02 = 2;
408    r03 = 3;
409    r04 = 4;
410    r05 = 5;
411    r06 = 6;
412    r07 = 7;
413    r08 = 8;
414    r09 = 9;
415    r10 = 10;
416    r11 = 11;
417    r12 = 12;
418    r13 = 13;
419    r14 = 14;
420    r15 = 15;
421    r16 = 16;
422    r17 = 17;
423    r18 = 18;
424    r19 = 19;
425    r20 = 20;
426    r21 = 21;
427    r22 = 22;
428    r23 = 23;
429    r24 = 24;
430    r25 = 25;
431    r26 = 26;
432    r27 = 27;
433    r28 = 28;
434    r29 = 29;
435    r30 = 30;
436    r31 = 31;
437    r32 = 32;
438    r33 = 33;
439    r34 = 34;
440    r35 = 35;
441    r36 = 36;
442    r37 = 37;
443    r38 = 38;
444
445    d[0] = &r01 - &r00;
446    d[1] = &r02 - &r01;
447    d[2] = &r03 - &r02;
448    d[3] = &r05 - &r03;
449    d[4] = &r07 - &r05;
450    d[5] = &r09 - &r07;
451    d[6] = &r11 - &r09;
452    d[7] = &r13 - &r11;
453    d[8] = &r15 - &r13;
454    d[9] = &r17 - &r15;
455    d[10] = &r19 - &r17;
456    d[11] = &r21 - &r19;
457    d[12] = &r23 - &r21;
458    d[13] = &r25 - &r23;
459    d[14] = &r27 - &r25;
460    d[15] = &r29 - &r27;
461    d[16] = &r31 - &r29;
462    d[17] = &r33 - &r31;
463    d[18] = &r35 - &r33;
464    d[19] = &r36 - &r35;
465    d[20] = &r37 - &r36;
466    d[21] = &r38 - &r37;
467
468 /*   The following FSM analyzes the string of differences. It accepts
469 strings of the form a+b+a+ and returns 16 minus the number of bs,
470 which is the number of variables that actually got into registers.
471 Otherwise it signals rejection by returning -1., indicating that the
472 test is unreliable.              */
473
474    n1 = d[0];
475    s = 1;
476
477    for (j=0; j<22; j++)
478      switch (s) {
479        case 1: if (d[j] != n1) {
480                 n2 = d[j];
481                 s = 2;
482                 nr = 1;
483                }
484                break;
485        case 2: if (d[j] == n1) {
486                 s = 3;
487                 break;
488                }
489                if (d[j] == n2) {
490                 nr = nr+1;
491                 break;
492                }
493                s = 4;
494                break;
495        case 3: if (d[j] != n1) s = 4;
496                break;
497      }
498    ;
499
500    if (s == 3) return 16-nr;
501    else return -1;
502 }
503 regp() {     /*   pointer to register assignment   */
504 /*   Testing a variable whose storage class has been spec-
505 ified as "register" is somewhat tricky, but it can be done in a
506 fairly reliable fashion by taking advantage of our knowledge of the
507 ways in which compilers operate. If we declare a collection of vari-
508 ables of the same storage class, we would expect that, when storage
509 for these variables is actually allocated, the variables will be
510 bunched together and ordered according to one of the following
511 criteria:
512
513      (a) the order in which they were defined.
514      (b) the order in which they are used.
515      (c) alphabetically.
516      (d) the order in which they appear in the compiler's
517          symbol table.
518      (e) some other way.
519
520      Hence, if we define a sequence of variables in close alpha-
521 betical order, and use them in the same order in which we define
522 them, we would expect the differences between the addresses of
523 successive variables to be constant, except in case (d) where the
524 symbol table is a hash table, or in case (e). If a subsequence in
525 the middle of this sequence is selected, and for this subsequence,
526 every other variable is specified to be "register", and address
527 differences are taken between adjacent nonregister variables, we would
528 still expect to find constant differences if the "register" vari-
529 ables were actually assigned to registers, and some other diff-
530 erences if they were not. Specifically, if we had N variables
531 specified as "register" of which the first n were actually ass-
532 igned to registers, we would expect the sequence of differences
533 to consist of a number of occurrences of some number, followed by
534 N-n occurrences of some other number, followed by several occurr-
535 ences of the first number. If we get a sequence like this, we can
536 determine, by simple subtraction, how many (if any) variables are
537 being assigned to registers. If we get some other sequence, we know
538 that the test is invalid.                                     */
539
540             int *r00;
541             int *r01;
542             int *r02;
543             int *r03;
544    register int *r04;
545             int *r05;
546    register int *r06;
547             int *r07;
548    register int *r08;
549             int *r09;
550    register int *r10;
551             int *r11;
552    register int *r12;
553             int *r13;
554    register int *r14;
555             int *r15;
556    register int *r16;
557             int *r17;
558    register int *r18;
559             int *r19;
560    register int *r20;
561             int *r21;
562    register int *r22;
563             int *r23;
564    register int *r24;
565             int *r25;
566    register int *r26;
567             int *r27;
568    register int *r28;
569             int *r29;
570    register int *r30;
571             int *r31;
572    register int *r32;
573             int *r33;
574    register int *r34;
575             int *r35;
576             int *r36;
577             int *r37;
578             int *r38;
579
580    int s, n1, n2, nr, j, d[22];
581
582    r00 = (int *)&r00;
583    r01 = (int *)&r01;
584    r02 = (int *)&r02;
585    r03 = (int *)&r03;
586    r04 = (int *)&r05;
587    r05 = (int *)&r05;
588    r06 = (int *)&r07;
589    r07 = (int *)&r07;
590    r08 = (int *)&r09;
591    r09 = (int *)&r09;
592    r10 = (int *)&r11;
593    r11 = (int *)&r11;
594    r12 = (int *)&r13;
595    r13 = (int *)&r13;
596    r14 = (int *)&r15;
597    r15 = (int *)&r15;
598    r16 = (int *)&r17;
599    r17 = (int *)&r17;
600    r18 = (int *)&r19;
601    r19 = (int *)&r19;
602    r20 = (int *)&r21;
603    r21 = (int *)&r21;
604    r22 = (int *)&r23;
605    r23 = (int *)&r23;
606    r24 = (int *)&r25;
607    r25 = (int *)&r25;
608    r26 = (int *)&r27;
609    r27 = (int *)&r27;
610    r28 = (int *)&r29;
611    r29 = (int *)&r29;
612    r30 = (int *)&r31;
613    r31 = (int *)&r31;
614    r32 = (int *)&r33;
615    r33 = (int *)&r33;
616    r34 = (int *)&r35;
617    r35 = (int *)&r35;
618    r36 = (int *)&r36;
619    r37 = (int *)&r37;
620    r38 = (int *)&r38;
621
622    d[0] = &r01 - &r00;
623    d[1] = &r02 - &r01;
624    d[2] = &r03 - &r02;
625    d[3] = &r05 - &r03;
626    d[4] = &r07 - &r05;
627    d[5] = &r09 - &r07;
628    d[6] = &r11 - &r09;
629    d[7] = &r13 - &r11;
630    d[8] = &r15 - &r13;
631    d[9] = &r17 - &r15;
632    d[10] = &r19 - &r17;
633    d[11] = &r21 - &r19;
634    d[12] = &r23 - &r21;
635    d[13] = &r25 - &r23;
636    d[14] = &r27 - &r25;
637    d[15] = &r29 - &r27;
638    d[16] = &r31 - &r29;
639    d[17] = &r33 - &r31;
640    d[18] = &r35 - &r33;
641    d[19] = &r36 - &r35;
642    d[20] = &r37 - &r36;
643    d[21] = &r38 - &r37;
644
645 /*   The following FSM analyzes the string of differences. It accepts
646 strings of the form a+b+a+ and returns 16 minus the number of bs,
647 which is the number of variables that actually got into registers.
648 Otherwise it signals rejection by returning -1., indicating that the
649 test is unreliable.              */
650
651    n1 = d[0];
652    s = 1;
653    for (j=0; j<22; j++)
654      switch (s) {
655        case 1: if (d[j] != n1) {
656                 n2 = d[j];
657                 s = 2;
658                 nr = 1;
659                }
660                break;
661        case 2: if (d[j] == n1) {
662                 s = 3;
663                 break;
664                }
665                if (d[j] == n2) {
666                 nr = nr+1;
667                 break;
668                }
669                s = 4;
670                break;
671        case 3: if (d[j] != n1) s = 4;
672                break;
673      }
674    ;
675
676    if (s == 3) return 16-nr;
677    else return -1;
678 }
679
680 /*********************************************************************************************
681  the main loop that launches the sections
682 *********************************************************************************************/
683
684 #ifndef NO_TYPELESS_STRUCT_PTR
685         int section(int j,struct* pd0){
686 #else
687         int section(int j,void* pd0){
688 #endif
689         switch(j){
690                 case 0: return s81(pd0);
691         }
692 }
693
694 #define cq_sections 1
695
696 /*
697         C REFERENCE MANUAL (main)
698 */
699
700 #ifndef NO_OLD_FUNC_DECL
701 main(n,args)
702 int n;
703 char **args;
704 {
705 #else
706 int main(int n,char **args) {
707 #endif
708
709 int j;
710 static struct defs d0, *pd0;
711         
712    d0.flgs = 1;          /* These flags dictate            */
713    d0.flgm = 1;          /*     the verbosity of           */
714    d0.flgd = 1;          /*         the program.           */
715    d0.flgl = 1;
716
717    pd0 = &d0;
718
719    for (j=0; j<cq_sections; j++) {
720      d0.rrc=section(j,pd0);
721      d0.crc=d0.crc+d0.rrc;
722      if(d0.flgs != 0) printf("Section %s returned %d.\n",d0.rfs,d0.rrc);
723    }
724
725    if(d0.crc == 0) printf("\nNo errors detected.\n");
726    else printf("\nFailed.\n");
727
728    return d0.crc;
729 }