mac-tip/mac-cpp-source/utils/PascalLib.c

262 lines
6.9 KiB
C

/*
* 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 <ctype.h>
#include <string.h>
#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