/* * Library for handling Pascal-Strings * * by Thomas Tempelmann, macdev@tempel.org * * Originally by Markus Fritze. * Changes and additions by Thomas Tempelmann: * - pstrlen neu * - BlockMoveData statt BlockMove * - pstrcmp liefert nicht Boolean sondern short, wie bei strcmp. * - pstrupper neu * 28.12.95 TT: * - alle Zugriffe auf s[0] und d[0] word-expandiert, bevor mit ihnen gerechnet wird, * um zu verhindern, da§ bei der LŠnge 255 ein †berlauf nach 0 passiert. * 08.04.95 TT: * - pstrcmp() lieferte "C"<"BB", da das LŠngenbyte mit verglichen wurde. Korrigiert. * - BlockMoveData() durch copyBytes() ersetzt, da vermutlich i.d.R. schneller. * 09.04.95 TT: * - Geschw-optimiert: pfindchar, pstrupper, pdelchars * - pstrextract() neu * 30.4.96 TT: * - copyBytes kopierte falsch, wenn source und dest sich Ÿberlagern und dest>source war. * 18.7.96 TT: * - strcatc neu * 14.8.96 TT: * - sicherheitshalber 'far' accesses eingefŸhrt. * 23.07.00 TT: * - disabled the "far" pragmas * - changed "StringPtr" into "unsigned char*" so that it can be compiled for Windows, too. */ #include #include #include "PascalLib.h" #pragma push #pragma cplusplus on /* * We need far data access in this module * (alternatively we could setup A5 appropriately): */ /* !TT July 23, 2000 - removed this #ifndef __powerc #pragma far_data on #pragma far_strings on #pragma far_vtables on #endif */ static void copyBytes (const unsigned char* s0, unsigned char* d, unsigned short len) { const unsigned char* s = s0; if (d > s) { // rŸckwŠrts kopieren if (len) { d += len; s += len; do { *--d = *--s; } while (--len); } } else { if (len) do { *d++ = *s++; } while (--len); } } void pstrcpy (unsigned char* d, const unsigned char* s) { copyBytes (s, d, ((unsigned short)s[0])+1); } void pstrncpy (unsigned char* d, const unsigned char* s, short n) // n: dest buffer size including length char { if (n) { if (n > ((unsigned short)s[0])+1) n = ((unsigned short)s[0])+1; copyBytes (s, d, n); if (n < ((unsigned short)d[0])+1) d[0] = n-1; } } void pstrcat (unsigned char* d, const unsigned char* s) { copyBytes (s + 1, d + ((unsigned short)d[0]) + 1, s[0]); d[0] += s[0]; } void pstrcatc (unsigned char* d, const char* s) { short n = strlen(s); copyBytes ((unsigned char*)s, d + ((unsigned short)d[0]) + 1, n); d[0] += n; } void pstrcatchar (unsigned char* d, const unsigned char c) { d[++d[0]] = c; } short pfindchar (const unsigned char* d, const unsigned char c) { short i, dlen = d[0]; for (i = 1; i <= dlen; i++) { if (d[i] == c) return i; } return 0; } void pstrextract (unsigned char* d, const unsigned char* s, short offset, short len) { short slen; if (offset < 1 || offset > (slen = s[0])) { d[0] = 0; return; } if (((offset-1) + len) > slen) { len = slen - offset + 1; } if (len <= 0) { d[0] = 0; return; } copyBytes (s + offset, d + 1, len); d[0] = len; } void pdelchars (unsigned char* d, short offset, short len) { short dlen; if (offset > (dlen = d[0])) return; // Offset zu gro§ if (len <= 0) return; // LŠnge zu klein if ((offset + len) > (dlen + 1)) { // LŠnge zu gro§? d[0] = offset; // String zurechtstutzen return; } copyBytes (d + offset + len, d + offset, dlen - len - offset + 1); d[0] -= len; } void pstrins (unsigned char* d, const unsigned char* s, short offset) { short slen, dlen; if ((slen = s[0]) == 0) return; // einzufŸgender String = 0 Bytes => raus if (offset > (dlen = d[0])) { // ggf. an den String anhŠngen offset = dlen + 1; } copyBytes (d + offset, d + offset + slen, dlen + 1 - offset); // String nach hinten copyBytes (s + 1, d + offset, slen); // String einfŸgen d[0] += slen; // und die LŠnge updaten } short pstrcmp (const unsigned char* s10, const unsigned char* s20) { const unsigned char* s1 = s10; const unsigned char* s2 = s20; unsigned char l1 = *s1++, l2 = *s2++; unsigned char len = (l1 < l2)? l1:l2; if (len) do { if (*s1++ != *s2++) { return (s1[-1] < s2[-1])? -1: +1; } } while (--len); if (l1 == l2) { return 0; } else { return (l1 < l2)? -1: +1; } } short pstrlen (const unsigned char* s1) { return s1[0]; } void pstrupper (unsigned char* d) { short i, dlen = d[0]; for (i = 1; i <= dlen; i++) { d[i] = toupper (d[i]); } } typedef unsigned char byte; /* short pfindstr (const unsigned char* target, const unsigned char* search) { unsigned char* s = search; unsigned char* d = target; short slen = s[0]; if (slen) { short i; short iend = d[0] - slen + 1; for (i = 1; i <= iend; i++) { if (d[i] == s[1]) { short len = slen - 1; if (len) { unsigned char* s1 = &s[2], d1 = &d[i+1]; do { if (*s1++ != *d1++) { break; } } while (--len); } if (len == 0) return i; } } } return 0; } */ short pfindstr (const unsigned char* d, const unsigned char* s0) { const unsigned char* s = s0; short slen = *s++; if (slen == 0) return 0; --slen; { byte c = *s++; short i; short end = d[0] - slen; for (i = 1; i <= end; i++) { if (d[i] == c) { const byte *sp = s, *dp = &d[i+1]; byte len = slen; do { if (len-- == 0) return i; // gefunden } while (*sp++ == *dp++); } } } return 0; } void pstrnins (unsigned char* d, short destSize, const unsigned char* s, short offset) // TT 25 Sep 97: does no write over end of dest string // 'destSize': size of dest string including length byte { short slen, dlen; if (offset < 1) return; if ((slen = s[0]) == 0) return; // einzufŸgender String = 0 Bytes => raus if (offset > (dlen = d[0])) { // ggf. an den String anhŠngen offset = dlen + 1; } if (offset >= destSize) return; if (offset + slen > destSize) { slen = destSize - offset; dlen = offset - 1; } else { if (slen + dlen >= destSize) { dlen = destSize - 1 - slen; } copyBytes (d + offset, d + offset + slen, dlen + 1 - offset); // String nach hinten } copyBytes (s + 1, d + offset, slen); // String einfŸgen d[0] = dlen + slen; // und die LŠnge updaten } #pragma pop