1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/types.h>
30 #include "codeset.h"
31 #include "mbextern.h"
32 #include "iso2022.h"
33
34 #define TO_MULTI 2
35 #define TO_SINGLE 1
36
37 #define BIT7ENV 7 /* 7bit enviornment */
38 #define BIT8ENV 8 /* 8bit environment */
39 #define NUM_OF_STATES 4 /* G0, G1, G2, G3 */
40 #define BIT8(_ch) (_ch & 0x80)
41 #define MAXSIZE 100 /* ESC LOCK upper lower */
42
43 #define USE_STATE 0 /* use the actual _state info */
44 #define USE_CONTROL 1 /* use C0 or C1 */
45 #define USE_SS2 2 /* use Single shift 2 */
46 #define USE_SS3 3 /* use Single shift 3 */
47
48 #define G0MASK 0x0000
49 #define G1MASK 0x0080
50 #define G2MASK 0x8000
51 #define G3MASK 0x8080
52 #define FINAL 0x33 /* Temporary final character */
53
54 #define MMB_CUR_MAX 128
55
56 /*
57 * Keep state informations
58 */
59 struct state {
60 char width; /* 1 or 2 */
61 char final; /* final character */
62 };
63
64 static char _my_env = BIT7ENV; /* default 7bits environment */
65 static struct state Invoked_G0, Invoked_G1;
66 static char _currentG0 = G0;
67 static char _currentG1 = G1;
68 static struct state _des_states[NUM_OF_STATES] = {
69 {-1, 0}, {-1, 0}, {-1, 0}, {01, 0}
70 };
71
72 void _savestates(void); /* save states */
73 void _restorestates(void); /* restore states */
74 void _initializestates(void);/* Initialize states */
75
76
77 /*
78 * Variables for wc*tomb*()
79 */
80 static char _currentOUT = G0; /* G0, G1, G2 or G3 */
81 static int prevcsize = 1;
82
83 /*
84 * mbtowc - subroutine for most iso codeset sequences
85 */
86 int
_mbtowc_iso(wchar_t * pwc,char * s,size_t n)87 _mbtowc_iso(wchar_t *pwc, char *s, size_t n)
88 {
89 unsigned char ch;
90 unsigned char tch; /* temporary use */
91 unsigned char *us = (unsigned char *)s;
92 int gen_wide_state = USE_STATE; /* used in gen_wide: */
93 int length = 0;
94 int len = 0;
95 wchar_t wide;
96 int mask;
97 int i;
98
99 isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
100
101 /*
102 * initialize _g0_stuff
103 */
104 if (_des_states[G0].width == -1) {
105 _des_states[G0].width = isoinfo->g0_len;
106 _des_states[G1].width = isoinfo->g1_len;
107 _des_states[G2].width = isoinfo->g2_len;
108 _des_states[G3].width = isoinfo->g3_len;
109 _my_env = isoinfo->bit_env;
110
111 Invoked_G0 = _des_states[G0];
112 Invoked_G1 = _des_states[G1];
113 }
114
115 /*
116 * get character and proceed
117 */
118 loop:
119 ch = *us++;
120 if (++length > n) return (-1); /* too long */
121 switch (ch) { /* get a character */
122 /* escape sequence or locking shifts */
123 case ESC: /* escape sequence */
124 gen_wide_state = USE_STATE; /* used in gen_wide: */
125 ch = *us++;
126 if (++length > n) return (-1); /* too long */
127 switch (ch) {
128 /* DESIGNATE */
129 case 0x24: /* designate */
130 ch = *us++;
131 if (++length > n) return (-1); /* too long */
132 switch (ch) {
133 case 0x28: case 0x29:
134 case 0x2A: case 0x2B:
135 case 0x2D: case 0x2E:
136 case 0x2F:
137 tch = ch; /* save this to decide _des_state */
138 /* Skip intermidiates */
139 do {
140 ch = *us++;
141 if (++length > n) return (-1); /* too long */
142 } while (ch >= 0x20 && ch <= 0x2F);
143 if (ch < 0x30) /* ch should be a final character */
144 return (-1); /* error */
145 if (tch == 0x28)
146 i = G0;
147 else if (tch == 0x29 || tch == 0x2D)
148 i = G1;
149 else if (tch == 0x2A || tch == 0x2E)
150 i = G2;
151 else /* (tch == 0x2B || tch == 0x2F) */
152 i = G3;
153 /* updates state info */
154 _des_states[i].width = TO_MULTI;
155 _des_states[i].final = ch;
156
157 goto loop;
158 break;
159 default:
160 /* This is an illegal sequence */
161 return (-1);
162 break;
163 }
164 break;
165 case 0x28: /* designate */
166 case 0x29: case 0x2A: case 0x2B:
167 case 0x2D: case 0x2E: case 0x2F:
168 tch = ch; /* save this to decide _des_state */
169 /* Skip intermidiates */
170 do {
171 ch = *us++;
172 if (++length > n) return (-1); /* too long */
173 } while (ch >= 0x20 && ch <= 0x2F);
174 if (ch < 0x30) /* ch should be a final character */
175 return (-1); /* error */
176 if (tch == 0x28)
177 i = G0;
178 else if (tch == 0x29 || tch == 0x2D)
179 i = G1;
180 else if (tch == 0x2A || tch == 0x2E)
181 i = G2;
182 else /* (tch == 0x2B || tch == 0x2F) */
183 i = G3;
184 /* updates state info */
185 _des_states[i].width = TO_SINGLE;
186 _des_states[i].final = ch;
187
188 goto loop;
189 break;
190
191 /* LOCKING SHIFTS */
192 case LS1R: /* locking shift LS1R */;
193 Invoked_G1 = _des_states[G1];
194 _currentG1 = G1;
195 goto loop;
196 break;
197 case LS2: /* locking shift LS2 */
198 Invoked_G0 = _des_states[G2];
199 _currentG0 = G2;
200 goto loop;
201 break;
202 case LS2R: /* locking shift LS2R */
203 Invoked_G1 = _des_states[G2];
204 _currentG1 = G2;
205 goto loop;
206 break;
207 case LS3: /* locking shift LS3 */
208 Invoked_G0 = _des_states[G3];
209 _currentG0 = G3;
210 goto loop;
211 break;
212 case LS3R: /* locking shift LS3R */
213 Invoked_G1 = _des_states[G3];
214 _currentG1 = G3;
215 goto loop;
216 break;
217
218 /* CONTROL FUNCTIONS */
219 case 0x21: /* C0 sets */
220 case 0x22: /* C1 sets */
221 do {
222 ch = *us++;
223 if (++length > n) return (-1); /* too long */
224 } while (ch >= 0x20 && ch <= 0x2F);
225 if (ch < 0x30) /* ch should be a final character */
226 return (-1); /* error */
227 goto loop;
228 break;
229
230 /* SINGLE SHIFT for 7bit environment */
231 case SS2_7B: /* Single shift SS2 for 7bits */
232 case SS3_7B: /* Single shoft SS3 for 7bits */
233 if (ch == SS2_7B)
234 gen_wide_state = USE_SS2;
235 else
236 gen_wide_state = USE_SS3;
237 goto loop;
238 break;
239
240 default: /* should be an error */
241 return (-1);
242 break;
243 }
244 /* locking shifts */
245 case LS0:
246 gen_wide_state = USE_STATE; /* used in gen_wide: */
247 Invoked_G0 = _des_states[G0];
248 _currentG0 = G0;
249 goto loop;
250 break;
251
252 case LS1:
253 gen_wide_state = USE_STATE; /* used in gen_wide: */
254 Invoked_G0 = _des_states[G1];
255 _currentG0 = G1;
256 goto loop;
257 break;
258
259 /* Single shift SS3 and SS2 for 8bits */
260 case SS2_8B:
261 case SS3_8B:
262 if (ch == SS2_8B)
263 gen_wide_state = USE_SS2;
264 else
265 gen_wide_state = USE_SS3;
266 goto loop;
267 break;
268
269 /* This character is not any special character/
270 * It does not change any state.
271 * Goto where it generates wide character.
272 */
273 default:
274 /*
275 * Use this ch to generate pwc.
276 */
277 if (ch == 0) { /* end of string or 0 */
278 wide = 0;
279 mask = 0;
280 goto gen_wide;
281 }
282 break;
283 }
284
285
286 /*
287 * Generate pwc here.
288 * The information here is
289 * current state and length. If the length is two, you need to
290 * read one more character.
291 */
292 switch (gen_wide_state) {
293 case USE_STATE:
294 if (BIT8(ch)) { /* 8bit environment ? */
295 /* current mode is G1 mode */
296 if (Invoked_G1.width == 2) {
297 tch = *us++;
298 if (++length > n) return (-1);
299 wide = ch;
300 wide = (wide << 8 | tch);
301 }
302 else {
303 wide = ch;
304 }
305 if (_currentG1 == G0) mask = G0MASK;
306 else if (_currentG1 == G1) mask = G1MASK;
307 else if (_currentG1 == G2) mask = G2MASK;
308 else mask = G3MASK;
309 }
310 else {
311 /* current mode is G0 mode */
312 if (Invoked_G0.width == 2) {
313 tch = *us++;
314 if (++length > n) return (-1);
315 wide = ch;
316 wide = (wide << 8 | tch);
317 }
318 else {
319 wide = ch;
320 }
321 if (_currentG0 == G0) mask = G0MASK;
322 else if (_currentG0 == G1) mask = G1MASK;
323 else if (_currentG0 == G2) mask = G2MASK;
324 else mask = G3MASK;
325 }
326 break;
327 case USE_SS2:
328 if (_des_states[G2].width == 2) {
329 tch = *us++;
330 if (++length > n) return (-1);
331 wide = ch;
332 wide = (wide << 8 | tch);
333 }
334 else {
335 wide = ch;
336 }
337 mask = G2MASK;
338 break;
339 case USE_SS3:
340 if (_des_states[G3].width == 2) {
341 tch = *us++;
342 if (++length > n) return (-1);
343 wide = ch;
344 wide = (wide << 8 | tch);
345 }
346 else {
347 wide = ch;
348 }
349 mask = G3MASK;
350 break;
351 default:
352 /* shoult be internal error */
353 return (-1);
354 break;
355 }
356 gen_wide:
357 wide &= 0x7F7F; /* strip off the top bit */
358 wide = wide | mask;
359 if (pwc != NULL)
360 *pwc = wide;
361 return (length);
362 }
363
364
365 #define MAXMBSIZE 128
366 /*
367 * mbstowcs()
368 */
369 size_t
_mbstowcs_iso(wchar_t * pwcs,unsigned char * s,size_t n)370 _mbstowcs_iso(wchar_t *pwcs, unsigned char *s, size_t n)
371 {
372 int ret1;
373 int accsum = 0;
374 wchar_t pwc;
375
376 /*
377 * If pwcs == 0, do nothing.
378 */
379 if (pwcs == 0)
380 return (0);
381 /*
382 * States things
383 */
384 _savestates(); _initializestates();
385 while (accsum < n) {
386 ret1 = _mbtowc_iso (&pwc, (char *)s, MAXMBSIZE);
387 if (ret1 < 0)
388 return (-1); /* error */
389 if (ret1 == 0 || pwc == 0) {
390 if (pwcs == 0)
391 *pwcs = 0;
392 /*
393 * Restore states
394 */
395 _restorestates();
396 return (accsum);
397 }
398 s = s + ret1; /* increment the pointer */
399 *pwcs++ = pwc;
400 ++accsum;
401 }
402 /*
403 * Restore states
404 */
405 _restorestates();
406 return (accsum);
407 }
408
409 /*
410 * wctomb -
411 */
412 int
_wctomb_iso(unsigned char * s,wchar_t pwc)413 _wctomb_iso(unsigned char *s, wchar_t pwc)
414 {
415 unsigned char ch;
416 unsigned char tch; /* temporary use */
417 unsigned char *us = (unsigned char *)s;
418 int gen_wide_state = USE_STATE; /* used in gen_wide: */
419 int length = 0;
420 int len = 0;
421 wchar_t wide;
422 unsigned short mode;
423 unsigned char buf[MAXSIZE];
424 unsigned char *bp;
425 int csize, i;
426 int n = MMB_CUR_MAX;
427
428 isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info;
429
430 /*
431 * If pwc is 0, do this first.
432 */
433 if (pwc == 0) {
434 if (s != 0) {
435 *s = 0;
436 return (1);
437 }
438 else {
439 return (0);
440 }
441 }
442
443 mode = pwc & G3MASK; /* The mode of this character */
444 if (((pwc >> 8) & 0x007f) == 0)
445 csize = 1;
446 else
447 csize = 2;
448 bp = buf;
449 length = 0;
450 #ifdef DDDebug
451 if (_my_env == BIT7ENV)
452 printf ("7b ");
453 else
454 printf ("8b ");
455 printf ("csize = %d, prevcsize = %d, (%x,%x) ",csize, prevcsize, (pwc>>8)&0x00ff, pwc&0x00ff);
456 switch (mode) {
457 case G0MASK:
458 printf ("G0"); break;
459 case G1MASK:
460 printf ("G1"); break;
461 case G2MASK:
462 printf ("G2"); break;
463 case G3MASK:
464 printf ("G3"); break;
465 default:
466 printf ("XXXX"); break;
467 }
468 #endif
469
470 switch (_my_env) {
471 case BIT7ENV: /* 7 bit environment */
472 switch (mode) {
473 case G0MASK:
474 if (_currentOUT != G0 || prevcsize != csize) {
475 _currentOUT = G0;
476 if (csize == 2) {
477 /*
478 * Emit escape sequences
479 */
480 *bp++ = ESC;
481 *bp++ = 0x24;
482 *bp++ = 0x28;
483 *bp++ = FINAL;
484 length += 4;
485 }
486 else {
487 /*
488 * Emit escape sequences
489 */
490 *bp++ = ESC;
491 *bp++ = 0x28;
492 *bp++ = FINAL;
493 length += 3;
494 }
495 *bp++ = SI;
496 ++length;
497 }
498 if (csize == 1) {
499 *bp++ = pwc & 0x007f;
500 ++length;
501 }
502 else {
503 *bp++ = (pwc & 0x7f00) >> 8;
504 ++length;
505 *bp++ = pwc & 0x007f;
506 ++length;
507 }
508 break;
509 case G1MASK:
510 if (_currentOUT != G1 || prevcsize != csize) {
511 _currentOUT = G1;
512 if (csize == 2) {
513 /*
514 * Emit escape sequences
515 */
516 *bp++ = ESC;
517 *bp++ = 0x24;
518 *bp++ = 0x29;
519 *bp++ = FINAL;
520 length += 4;
521 }
522 else {
523 /*
524 * Emit escape sequences
525 */
526 *bp++ = ESC;
527 *bp++ = 0x29;
528 *bp++ = FINAL;
529 length += 3;
530 }
531 *bp++ = SO;
532 ++length;
533 }
534 if (csize == 1) {
535 *bp++ = pwc & 0x007f;
536 ++length;
537 }
538 else {
539 *bp++ = (pwc & 0x7f00) >> 8;
540 ++length;
541 *bp++ = pwc & 0x007f;
542 ++length;
543 }
544 break;
545 case G2MASK:
546 if (_currentOUT != G2 || prevcsize != csize) {
547 _currentOUT = G2;
548 if (csize == 2) {
549 /*
550 * Emit escape sequences
551 */
552 *bp++ = ESC;
553 *bp++ = 0x24;
554 *bp++ = 0x2A;
555 *bp++ = FINAL;
556 length += 4;
557 }
558 else {
559 /*
560 * Emit escape sequences
561 */
562 *bp++ = ESC;
563 *bp++ = 0x2A;
564 *bp++ = FINAL;
565 length += 3;
566 }
567 *bp++ = ESC; *bp++ = LS2;
568 length += 2;
569 }
570 if (csize == 1) {
571 *bp++ = pwc & 0x007f;
572 ++length;
573 }
574 else {
575 *bp++ = (pwc & 0x7f00) >> 8;
576 ++length;
577 *bp++ = pwc & 0x007f;
578 ++length;
579 }
580 break;
581 case G3MASK:
582 if (_currentOUT != G3 || prevcsize != csize) {
583 _currentOUT = G3;
584 if (csize == 2) {
585 /*
586 * Emit escape sequences
587 */
588 *bp++ = ESC;
589 *bp++ = 0x24;
590 *bp++ = 0x2B;
591 *bp++ = FINAL;
592 length += 4;
593 }
594 else {
595 /*
596 * Emit escape sequences
597 */
598 *bp++ = ESC;
599 *bp++ = 0x2B;
600 *bp++ = FINAL;
601 length += 3;
602 }
603 *bp++ = ESC; *bp++ = LS3;
604 length += 2;
605 }
606 if (csize == 1) {
607 *bp++ = pwc & 0x007f;
608 ++length;
609 }
610 else {
611 *bp++ = (pwc & 0x7f00) >> 8;
612 ++length;
613 *bp++ = pwc & 0x007f;
614 ++length;
615 }
616 break;
617 }
618 break;
619 case BIT8ENV: /* 8 bit environment */
620 switch (mode) {
621 case G0MASK:
622 if (_currentOUT != G0 || prevcsize != csize) {
623 _currentOUT = G0;
624 if (csize == 2) {
625 /*
626 * Emit escape sequences
627 */
628 *bp++ = ESC;
629 *bp++ = 0x24;
630 *bp++ = 0x28;
631 *bp++ = FINAL;
632 length += 4;
633 }
634 else {
635 /*
636 * Emit escape sequences
637 */
638 *bp++ = ESC;
639 *bp++ = 0x28;
640 *bp++ = FINAL;
641 length += 3;
642 }
643 *bp++ = LS0;
644 ++length;
645 }
646 if (csize == 1) {
647 *bp++ = pwc & 0x007f;
648 ++length;
649 }
650 else {
651 *bp++ = (pwc & 0x7f00) >> 8;
652 ++length;
653 *bp++ = pwc & 0x007f;
654 ++length;
655 }
656 break;
657 case G1MASK:
658 if (_currentOUT != G1 || prevcsize != csize) {
659 _currentOUT = G1;
660 if (csize == 2) {
661 /*
662 * Emit escape sequences
663 */
664 *bp++ = ESC;
665 *bp++ = 0x24;
666 *bp++ = 0x29;
667 *bp++ = FINAL;
668 length += 4;
669 }
670 else {
671 /*
672 * Emit escape sequences
673 */
674 *bp++ = ESC;
675 *bp++ = 0x29;
676 *bp++ = FINAL;
677 length += 3;
678 }
679 *bp++ = ESC; *bp++ = LS1R;
680 length += 2;
681 }
682
683 /*
684 * If state is G1 or G2, or G3, assume that
685 * this is 8bit characters. To do this more
686 * accurately, wide character needs to be
687 * larger than 16 bits to keep more information.
688 */
689 pwc |= 0x8080;
690 if (csize == 1) {
691 *bp++ = pwc & 0x00ff;
692 ++length;
693 }
694 else {
695 *bp++ = (pwc & 0xff00) >> 8;
696 ++length;
697 *bp++ = pwc & 0x00ff;
698 ++length;
699 }
700 break;
701 case G2MASK:
702 if (_currentOUT != G2 || prevcsize != csize) {
703 _currentOUT = G2;
704 if (csize == 2) {
705 /*
706 * Emit escape sequences
707 */
708 *bp++ = ESC;
709 *bp++ = 0x24;
710 *bp++ = 0x2A;
711 *bp++ = FINAL;
712 length += 4;
713 }
714 else {
715 /*
716 * Emit escape sequences
717 */
718 *bp++ = ESC;
719 *bp++ = 0x2A;
720 *bp++ = FINAL;
721 length += 3;
722 }
723 *bp++ = ESC; *bp++ = LS2R;
724 length += 2;
725 }
726 /*
727 * If state is G1 or G2, or G3, assume that
728 * this is 8bit characters. To do this more
729 * accurately, wide character needs to be
730 * larger than 16 bits to keep more information.
731 */
732 pwc |= 0x8080;
733 if (csize == 1) {
734 *bp++ = pwc & 0x00ff;
735 ++length;
736 }
737 else {
738 *bp++ = (pwc & 0xff00) >> 8;
739 ++length;
740 *bp++ = pwc & 0x00ff;
741 ++length;
742 }
743 break;
744 case G3MASK:
745 if (_currentOUT != G3 || prevcsize != csize) {
746 _currentOUT = G3;
747 if (csize == 2) {
748 /*
749 * Emit escape sequences
750 */
751 *bp++ = ESC;
752 *bp++ = 0x24;
753 *bp++ = 0x2B;
754 *bp++ = FINAL;
755 length += 4;
756 }
757 else {
758 /*
759 * Emit escape sequences
760 */
761 *bp++ = ESC;
762 *bp++ = 0x2B;
763 *bp++ = FINAL;
764 length += 3;
765 }
766 *bp++ = ESC; *bp++ = LS3R;
767 length += 2;
768 }
769 /*
770 * If state is G1 or G2, or G3, assume that
771 * this is 8bit characters. To do this more
772 * accurately, wide character needs to be
773 * larger than 16 bits to keep more information.
774 */
775 pwc |= 0x8080;
776 if (csize == 1) {
777 *bp++ = pwc & 0x00ff;
778 ++length;
779 }
780 else {
781 *bp++ = (pwc & 0xff00) >> 8;
782 ++length;
783 *bp++ = pwc & 0x00ff;
784 ++length;
785 }
786 break;
787 }
788 break;
789 default: /* Should never happens */
790 return (-1);
791 break;
792 }
793
794 prevcsize = csize;
795
796 if (length > n) {
797 return (-1); /* buffer too small */
798 }
799 for (i = 0; i < length; i++) {
800 *s++ = buf[i];
801 }
802 #ifdef DDDebug
803 printf ("\t(");
804 for (i = 0; i < length; i++) {
805 printf ("%x,", buf[i]);
806 }
807 printf (")\n");
808 #endif
809 return (length);
810 }
811
812 /*
813 * wcstombs
814 */
815 size_t
_wcstombs_iso(char * s,wchar_t * pwcs,int n)816 _wcstombs_iso(char *s, wchar_t *pwcs, int n)
817 {
818 int acclen = 0;
819 char buf[MMB_CUR_MAX];
820 int ret1;
821 int i;
822
823 if (n < 0)
824 return (-1);
825 /*
826 * Initialize State
827 */
828 _savestates(); _initializestates();
829 while (acclen < n) {
830 ret1 = _wctomb_iso ((unsigned char *)buf, *pwcs);
831 /*
832 * end of string ?
833 */
834 if (ret1 == 1 && buf[0] == 0) {
835 *s = 0;
836 /*
837 * restore states
838 */
839 _restorestates();
840 return (acclen);
841 }
842 /*
843 * Error ?
844 */
845 if (ret1 < 0)
846 return (-1);
847 acclen += ret1;
848 for (i = 0; i < ret1; i++)
849 *s++ = buf[i];
850 ++pwcs;
851 }
852
853 /*
854 * restore states
855 */
856 _restorestates();
857
858 /*
859 * return the length
860 */
861 return (acclen);
862 }
863
864
865 /*
866 * Supplementary routines
867 */
868
869 void
_initializestates(void)870 _initializestates(void)
871 {
872 _currentG0 = G0;
873 _currentG1 = G1;
874
875 _des_states[G0].width = -1; /* This makes it Initialize */
876
877 _currentOUT = G0;
878 prevcsize = 1;
879 }
880
881 static char SAVED_currentG0;
882 static char SAVED_currentG1;
883 static struct state SAVED_des_states[NUM_OF_STATES];
884 static struct state SAVED_Invoked_G0, SAVED_Invoked_G1;
885 static char SAVED_currentOUT = G0; /* G0, G1, G2 or G3 */
886 static int SAVED_prevcsize = 1;
887
888 void
_savestates(void)889 _savestates(void)
890 {
891
892 SAVED_currentG0 = _currentG0;
893 SAVED_currentG1 = _currentG1;
894
895 SAVED_des_states[G0] = _des_states[G0];
896 SAVED_des_states[G1] = _des_states[G1];
897 SAVED_des_states[G2] = _des_states[G2];
898 SAVED_des_states[G3] = _des_states[G3];
899
900 SAVED_Invoked_G0 = Invoked_G0;
901 SAVED_Invoked_G1 = Invoked_G1;
902
903 SAVED_currentOUT = _currentOUT;
904 SAVED_prevcsize = prevcsize;
905 }
906
907 void
_restorestates(void)908 _restorestates(void)
909 {
910 _currentG0 = SAVED_currentG0;
911 _currentG1 = SAVED_currentG1;
912
913 _des_states[G0] = SAVED_des_states[G0];
914 _des_states[G1] = SAVED_des_states[G1];
915 _des_states[G2] = SAVED_des_states[G2];
916 _des_states[G3] = SAVED_des_states[G3];
917
918 Invoked_G0 = SAVED_Invoked_G0;
919 Invoked_G1 = SAVED_Invoked_G1;
920
921 _currentOUT = SAVED_currentOUT;
922 prevcsize = SAVED_prevcsize;
923 }
924