| 1 |
/* macpcstr.c -- niftyapp library pascal/C combination strings |
| 2 |
*/ |
| 3 |
/* (C) Copyright 1995 by Carnegie Mellon University |
| 4 |
* All Rights Reserved. |
| 5 |
* |
| 6 |
* Permission to use, copy, modify, distribute, and sell this software |
| 7 |
* and its documentation for any purpose is hereby granted without |
| 8 |
* fee, provided that the above copyright notice appear in all copies |
| 9 |
* and that both that copyright notice and this permission notice |
| 10 |
* appear in supporting documentation, and that the name of Carnegie |
| 11 |
* Mellon University not be used in advertising or publicity |
| 12 |
* pertaining to distribution of the software without specific, |
| 13 |
* written prior permission. Carnegie Mellon University makes no |
| 14 |
* representations about the suitability of this software for any |
| 15 |
* purpose. It is provided "as is" without express or implied |
| 16 |
* warranty. |
| 17 |
* |
| 18 |
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO |
| 19 |
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
| 20 |
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE |
| 21 |
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 22 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN |
| 23 |
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING |
| 24 |
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
| 25 |
* SOFTWARE. |
| 26 |
*/ |
| 27 |
/* (C) Copyright 1990, 1991 by Christopher J. Newman |
| 28 |
* All Rights Reserved. |
| 29 |
* |
| 30 |
* Permission to use, copy, modify, distribute, and sell this software and its |
| 31 |
* documentation for any purpose is hereby granted without fee, provided that |
| 32 |
* the above copyright notice appear in all copies and that both that |
| 33 |
* copyright notice and this permission notice appear in supporting |
| 34 |
* documentation, and that the name of Christopher J. Newman not be used in |
| 35 |
* advertising or publicity pertaining to distribution of the software without |
| 36 |
* specific, written prior permission. Christopher J. Newman makes no |
| 37 |
* representations about the suitability of this software for any purpose. It |
| 38 |
* is provided "as is" without express or implied warranty. |
| 39 |
* |
| 40 |
* CHRISTOPHER J. NEWMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
| 41 |
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT |
| 42 |
* SHALL CHRISTOPHER J. NEWMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
| 43 |
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
| 44 |
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 45 |
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
| 46 |
* OF THIS SOFTWARE. |
| 47 |
* |
| 48 |
* Author: Christopher J. Newman |
| 49 |
* Message: This is a nifty program. |
| 50 |
* |
| 51 |
* Created 9/1/88, Assembly Code 6/27/90 |
| 52 |
*/ |
| 53 |
|
| 54 |
#ifdef THINK_C |
| 55 |
typedef unsigned char PCstr; |
| 56 |
|
| 57 |
/* assembler function prototypes */ |
| 58 |
void PtoPCstrcpy(void); |
| 59 |
void CtoPCstrcpy(void); |
| 60 |
void PCtoPCstrcpy(void); |
| 61 |
void PtoPCstrncpy(void); |
| 62 |
void CtoPCstrncpy(void); |
| 63 |
void PtoPCstrcat(void); |
| 64 |
void CtoPCstrcat(void); |
| 65 |
PCstr *PtoPCstr(void); |
| 66 |
PCstr *CtoPCstr(void); |
| 67 |
void SetPlen(void); |
| 68 |
PCstr *longtoPCstr(long); /* not in assembler */ |
| 69 |
|
| 70 |
void PtoPCstrcpy( /* PCstr *dest, *src */ ) |
| 71 |
{ |
| 72 |
asm 68000 { |
| 73 |
movea.l 8(sp),a0 ; a0 = src |
| 74 |
movea.l 4(sp),a1 ; a1 = dest |
| 75 |
clr.w d0 |
| 76 |
move.b (a0),d0 |
| 77 |
clr.b 1(a1,d0) |
| 78 |
@loop: |
| 79 |
move.b (a0)+,(a1)+ |
| 80 |
dbf.w d0,@loop |
| 81 |
} |
| 82 |
} |
| 83 |
|
| 84 |
void CtoPCstrcpy( /* PCstr *dest, char *src */) |
| 85 |
{ |
| 86 |
asm 68000 { |
| 87 |
movea.l 8(sp),a0 ; a0 = src |
| 88 |
movea.l 4(sp),a1 ; a1 = dest |
| 89 |
addq.l #1,a1 |
| 90 |
moveq.l #-1,d0 |
| 91 |
@loop: |
| 92 |
addq.w #1,d0 |
| 93 |
move.b (a0)+,(a1)+ |
| 94 |
bne.s @loop |
| 95 |
movea.l 4(sp),a1 ; a1 = dest |
| 96 |
move.b d0,(a1) |
| 97 |
} |
| 98 |
} |
| 99 |
|
| 100 |
void PCtoPCstrcpy( /* PCstr *dest, PCstr *src */) |
| 101 |
{ |
| 102 |
asm 68000 { |
| 103 |
movea.l 8(sp),a0 ; a0 = src |
| 104 |
movea.l 4(sp),a1 ; a1 = dest |
| 105 |
move.b (a0)+,(a1)+ |
| 106 |
@loop: |
| 107 |
move.b (a0)+,(a1)+ |
| 108 |
bne.s @loop |
| 109 |
} |
| 110 |
} |
| 111 |
|
| 112 |
void PtoPCstrncpy( /* PCstr *dest, char *src, short n */) |
| 113 |
{ |
| 114 |
asm 68000 { |
| 115 |
movea.l 8(sp),a0 ; a0 = src |
| 116 |
movea.l 4(sp),a1 ; a1 = dest |
| 117 |
move.w 12(sp),d0 ; d0 = n |
| 118 |
clr.w d1 |
| 119 |
move.b (a0)+,d1 |
| 120 |
cmp.w d0,d1 |
| 121 |
bcc.s @skip |
| 122 |
move.w d1,d0 |
| 123 |
@skip: |
| 124 |
move.b d0,(a1)+ |
| 125 |
subq.w #1,d0 |
| 126 |
bcs.s @exit |
| 127 |
@loop: |
| 128 |
move.b (a0)+,(a1)+ |
| 129 |
dbf d0,@loop |
| 130 |
@exit: |
| 131 |
} |
| 132 |
} |
| 133 |
|
| 134 |
void CtoPCstrncpy( /* PCstr *dest, char *src, short n */ ) |
| 135 |
{ |
| 136 |
asm 68000 { |
| 137 |
movea.l 8(sp),a0 ; a0 = src |
| 138 |
movea.l 4(sp),a1 ; a1 = dest |
| 139 |
addq.l #1,a1 |
| 140 |
clr.w d1 |
| 141 |
move.w 12(sp),d0 ; d0 = n |
| 142 |
bra.s @skip |
| 143 |
@loop: |
| 144 |
addq.w #1,d1 |
| 145 |
move.b (a0)+,(a1)+ |
| 146 |
@skip: |
| 147 |
dbeq.w d0,@loop |
| 148 |
clr.b (a1) |
| 149 |
movea.l 4(sp),a1 ; a1 = dest |
| 150 |
subq.w #1,d1 |
| 151 |
move.b d1,(a1) |
| 152 |
} |
| 153 |
} |
| 154 |
|
| 155 |
void PtoPCstrcat( /* PCstr *dest, char *src */ ) |
| 156 |
{ |
| 157 |
asm 68000 { |
| 158 |
movea.l 8(sp),a0 ; a0 = src |
| 159 |
movea.l 4(sp),a1 ; a1 = dest |
| 160 |
clr.w d0 |
| 161 |
clr.w d1 |
| 162 |
move.b (a0)+,d0 |
| 163 |
move.b (a1),d1 |
| 164 |
add.b d0,(a1) |
| 165 |
lea.l 1(a1,d1),a1 |
| 166 |
bra.s @skip |
| 167 |
@loop: |
| 168 |
move.b (a0)+,(a1)+ |
| 169 |
@skip: |
| 170 |
dbf.w d0,@loop |
| 171 |
clr.b (a1) |
| 172 |
} |
| 173 |
} |
| 174 |
|
| 175 |
void CtoPCstrcat( /* PCstr *dest, char *src */ ) |
| 176 |
{ |
| 177 |
asm 68000 { |
| 178 |
movea.l 8(sp),a0 ; a0 = src |
| 179 |
movea.l 4(sp),a1 ; a1 = dest |
| 180 |
clr.w d0 |
| 181 |
move.b (a1),d0 |
| 182 |
lea.l 1(a1,d0),a1 |
| 183 |
subq.w #1,d0 |
| 184 |
@loop: |
| 185 |
addq.w #1,d0 |
| 186 |
move.b (a0)+,(a1)+ |
| 187 |
bne.s @loop |
| 188 |
movea.l 4(sp),a1 ; a1 = dest |
| 189 |
move.b d0,(a1) |
| 190 |
} |
| 191 |
} |
| 192 |
|
| 193 |
PCstr *PtoPCstr( /* char *str */ ) |
| 194 |
{ |
| 195 |
asm 68000 { |
| 196 |
movea.l 4(sp),a0 ; a0 = str |
| 197 |
clr.w d0 |
| 198 |
move.b (a0),d0 |
| 199 |
clr.b 1(a0,d0) |
| 200 |
move.l a0,d0 |
| 201 |
} |
| 202 |
} |
| 203 |
|
| 204 |
PCstr *CtoPCstr( /* char *str */) |
| 205 |
{ |
| 206 |
asm 68000 { |
| 207 |
movea.l 4(sp),a0 ; a0 = str |
| 208 |
move.b (a0)+,d0 |
| 209 |
lea.l (a0),a1 |
| 210 |
@loop: |
| 211 |
move.b (a1),d1 |
| 212 |
move.b d0,(a1)+ |
| 213 |
move.b d1,d0 |
| 214 |
bne.s @loop |
| 215 |
move.b d0,(a1) |
| 216 |
suba.l a0,a1 |
| 217 |
move.l a1,d0 |
| 218 |
move.b d0,-(a0) |
| 219 |
move.l a0,d0 |
| 220 |
} |
| 221 |
} |
| 222 |
|
| 223 |
void SetPlen( /* PCstr *pcstr */ ) |
| 224 |
{ |
| 225 |
asm 68000 { |
| 226 |
movea.l 4(sp),a0 ; a0 = str |
| 227 |
lea.l 1(a0),a1 |
| 228 |
moveq.l #-1,d0 |
| 229 |
@loop: |
| 230 |
addq.w #1,d0 |
| 231 |
@skip: |
| 232 |
tst.b (a1)+ |
| 233 |
bne.s @loop |
| 234 |
move.b d0,(a0) |
| 235 |
} |
| 236 |
} |
| 237 |
#else |
| 238 |
/* C function prototypes in mac_napp.h */ |
| 239 |
#include "macnapp.h" |
| 240 |
|
| 241 |
void PtoPCstrcpy(dest, src) |
| 242 |
register PCstr *dest; |
| 243 |
register char *src; |
| 244 |
{ |
| 245 |
register short i; |
| 246 |
|
| 247 |
i = Pstrlen(src); |
| 248 |
C(dest)[i] = '\0'; |
| 249 |
do { |
| 250 |
*dest++ = *src++; |
| 251 |
} while (i--); |
| 252 |
} |
| 253 |
|
| 254 |
void CtoPCstrcpy(dest, src) |
| 255 |
register PCstr *dest; |
| 256 |
register char *src; |
| 257 |
{ |
| 258 |
register short i; |
| 259 |
register char *cpy; |
| 260 |
|
| 261 |
cpy = C(dest); |
| 262 |
for (i = 0; *cpy++ = *src++; i++); |
| 263 |
*dest = i; |
| 264 |
} |
| 265 |
|
| 266 |
void PCtoPCstrcpy(dest, src) |
| 267 |
register PCstr *dest; |
| 268 |
register PCstr *src; |
| 269 |
{ |
| 270 |
*dest++ = *src++; |
| 271 |
while (*dest++ = *src++); |
| 272 |
} |
| 273 |
|
| 274 |
void PtoPCstrncpy(PCstr *dest, char *src, short n) |
| 275 |
{ |
| 276 |
if (Pstrlen(src) < n) n = Pstrlen(src); |
| 277 |
*dest++ = n; |
| 278 |
src++; |
| 279 |
while (n--) *dest++ = *src++; |
| 280 |
*dest++ = '\0'; |
| 281 |
} |
| 282 |
|
| 283 |
void CtoPCstrncpy(PCstr *dest, char *src, short n) |
| 284 |
{ |
| 285 |
register char *tmp; |
| 286 |
register short i; |
| 287 |
|
| 288 |
tmp = C(dest); |
| 289 |
for (i = 0; n-- && (*tmp++ = *src++); i++); |
| 290 |
*tmp = '\0'; |
| 291 |
*dest = i; |
| 292 |
} |
| 293 |
|
| 294 |
void PtoPCstrcat(dest, src) |
| 295 |
register PCstr *dest; |
| 296 |
register char *src; |
| 297 |
{ |
| 298 |
register short i; |
| 299 |
register short j; |
| 300 |
|
| 301 |
i = *dest; |
| 302 |
*dest += (j = (unsigned char) *src++); |
| 303 |
dest += i + 1; |
| 304 |
while (j--) *dest++ = *src++; |
| 305 |
*dest = '\0'; |
| 306 |
} |
| 307 |
|
| 308 |
void CtoPCstrcat(dest, src) |
| 309 |
register PCstr *dest; |
| 310 |
register char *src; |
| 311 |
{ |
| 312 |
register short i; |
| 313 |
register char *tmp; |
| 314 |
|
| 315 |
tmp = (char *) dest + (i = *dest) + 1; |
| 316 |
while (*tmp++ = *src++) i++; |
| 317 |
*dest = i; |
| 318 |
} |
| 319 |
|
| 320 |
PCstr *PtoPCstr(str) |
| 321 |
register char *str; |
| 322 |
{ |
| 323 |
SetClen((PCstr*) str); |
| 324 |
|
| 325 |
return ((PCstr*) str); |
| 326 |
} |
| 327 |
|
| 328 |
PCstr *CtoPCstr(str) |
| 329 |
register char *str; |
| 330 |
{ |
| 331 |
register PCstr i; |
| 332 |
register char c, d; |
| 333 |
register char *tmp; |
| 334 |
|
| 335 |
i = 0; |
| 336 |
tmp = str; |
| 337 |
tmp++; |
| 338 |
c = *tmp++; |
| 339 |
do { |
| 340 |
d = *tmp; |
| 341 |
*tmp++ = c; |
| 342 |
i++; |
| 343 |
} while (c = d); |
| 344 |
(*(PCstr*)str) = i; |
| 345 |
|
| 346 |
return ((PCstr*) str); |
| 347 |
} |
| 348 |
|
| 349 |
void SetPlen(pcstr) |
| 350 |
register PCstr *pcstr; |
| 351 |
{ |
| 352 |
register short i = -1; |
| 353 |
register char *len = C(pcstr); |
| 354 |
|
| 355 |
do { |
| 356 |
i++; |
| 357 |
} while (*len++); |
| 358 |
|
| 359 |
*pcstr = i; |
| 360 |
} |
| 361 |
#endif |
| 362 |
|
| 363 |
/* simple procedure to convert decimal number of |
| 364 |
* less than 20 digits to a PC string. |
| 365 |
* Compiling with 68020 option makes this quite a bit more efficient. |
| 366 |
*/ |
| 367 |
PCstr *longtoPCstr(i) |
| 368 |
register long i; |
| 369 |
{ |
| 370 |
static PCstr sbuf[21]; |
| 371 |
register Boolean negflag; |
| 372 |
register unsigned long val, ten = 10; |
| 373 |
register PCstr *pos = sbuf + sizeof (sbuf) - 1; |
| 374 |
register PCstr *posst; |
| 375 |
|
| 376 |
*pos = '\0'; |
| 377 |
posst = --pos; |
| 378 |
negflag = false; |
| 379 |
val = i; |
| 380 |
if (i < 0) { |
| 381 |
negflag = true; |
| 382 |
val = -i; |
| 383 |
} |
| 384 |
do { |
| 385 |
*pos = (unsigned short) (val % ten) + '0'; |
| 386 |
pos--; |
| 387 |
} while (val /= ten); |
| 388 |
if (negflag) { |
| 389 |
*pos = '-'; |
| 390 |
pos--; |
| 391 |
} |
| 392 |
*pos = posst - pos; |
| 393 |
|
| 394 |
return (pos); |
| 395 |
} |
| 396 |
|