| 645 | } |
| 646 | |
| 647 | static void psl_fix_utf8 (struct PSL_CTRL *PSL, char *in_string) { |
| 648 | /* Given in_string check if UTF8 characters are present and if so replace with PSL octal codes. Assumes ISOLatin1+ */ |
| 649 | unsigned int k, kout, use, utf8_codes = 0; |
| 650 | bool do_minus = (PSL->current.use_minus == PSL_TXTMODE_MINUS); |
| 651 | char *out_string = NULL; |
| 652 | |
| 653 | if (!strncmp (PSL->init.encoding, "Standard+", 9U) && do_minus) { /* For Standard+ encoding we may need to swap leading minus values encoded as hyphen with the actual minus symbol */ |
| 654 | for (k = 0; in_string[k]; k++) { |
| 655 | if ((k == 0 || in_string[k-1] != '@') && in_string[k] == 0055) /* Found a hyphen which we interpret to be a minus sign */ |
| 656 | in_string[k] = 0224; /* Minus is octal 224 in Standard+ but not present in just Standard */ |
| 657 | } |
| 658 | } |
| 659 | |
| 660 | if (strncmp (PSL->init.encoding, "ISOLatin1", 9U)) return; /* Do nothing unless ISOLatin[+] */ |
| 661 | |
| 662 | for (k = 0; in_string[k]; k++) { |
| 663 | if ((unsigned char)(in_string[k]) == 0303 || (unsigned char)(in_string[k]) == 0305) |
| 664 | utf8_codes++; /* Count them up */ |
| 665 | else if (k == 0 || in_string[k-1] != '@') { |
| 666 | if ((unsigned char)in_string[k] == 0255 && do_minus) |
| 667 | in_string[k] = 0055; /* Minus symbol is octal 0055 in ISOLatin1 */ |
| 668 | else if ((unsigned char)in_string[k] == 0055 && !do_minus) |
| 669 | in_string[k] = 0255; /* Hyphen symbol is octal 0255 in ISOLatin1 */ |
| 670 | } |
| 671 | } |
| 672 | if (utf8_codes == 0) return; /* Nothing to do */ |
| 673 | |
| 674 | out_string = PSL_memory (PSL, NULL, strlen(in_string) + 1, char); /* Get a new string of same length (extra byte for '\0') */ |
| 675 | |
| 676 | for (k = kout = 0; in_string[k]; k++) { |
| 677 | if ((unsigned char)(in_string[k]) == 0303) { /* Found octal 303 */ |
| 678 | k++; /* Skip the control code */ |
| 679 | if ((use = psl_ut8_code_to_ISOLatin (in_string[k]))) /* Found a 2-char utf8 combo, replace with single octal code from our table */ |
| 680 | out_string[kout++] = use; |
| 681 | else { /* Not a recognized code - just output both as they were given */ |
| 682 | out_string[kout++] = in_string[k-1]; |
| 683 | out_string[kout++] = in_string[k]; |
| 684 | } |
| 685 | } |
| 686 | else if ((unsigned char)(in_string[k]) == 0305) { /* Found Ydieresis, ae, AE, L&l-slash and the S,Z,s,z carons */ |
| 687 | k++; /* Skip the control code */ |
| 688 | switch ((unsigned char)in_string[k]) { /* These 9 chars are placed all over the table so must have individual cases */ |
| 689 | case 0201: use = 0203; break; /* Lslash */ |
| 690 | case 0202: use = 0213; break; /* lslash */ |
| 691 | case 0222: use = 0200; break; /* ae */ |
| 692 | case 0223: use = 0210; break; /* AE */ |
| 693 | case 0240: use = 0206; break; /* Scaron */ |
| 694 | case 0241: use = 0177; break; /* scaron */ |
| 695 | case 0270: use = 0211; break; /* Ydieresis */ |
| 696 | case 0275: use = 0212; break; /* Zcaron */ |
| 697 | case 0276: use = 0037; break; /* zcaron */ |
| 698 | default: use = 0; break; /* Not one of the recognized ones in our table */ |
| 699 | } |
| 700 | if (use) /* Found a 2-char utf8 combo */ |
| 701 | out_string[kout++] = use; |
| 702 | else { /* Not a recognized code - just output both as they were given */ |
| 703 | out_string[kout++] = in_string[k-1]; |
| 704 | out_string[kout++] = in_string[k]; |
no test coverage detected