diff --git a/collects/tests/mzscheme/foreign-test.ss b/collects/tests/mzscheme/foreign-test.ss index d95b39cc6e..55a4fb0657 100644 --- a/collects/tests/mzscheme/foreign-test.ss +++ b/collects/tests/mzscheme/foreign-test.ss @@ -142,27 +142,26 @@ (ptr-set! p _int 5) (test 5 ptr-ref p _int) (test 0 ptr-ref (ptr-add p 3 _int) _int) - (memcpy p 3 _int p 0 1 _int) + (memcpy p 3 p 0 1 _int) (test 5 ptr-ref (ptr-add p 3 _int) _int) ;; A MzScheme `int' is always 4 bytes. - (memset p 1 _int 17 9 _int) + (memset p 1 17 9 _int) (test 5 ptr-ref p _int) (test #x11111111 ptr-ref (ptr-add p 4) _int) - (memset p 2 18 9 _int) + (memset p 2 18 (* 9 (ctype-sizeof _int))) (test #x12121212 ptr-ref (ptr-add p 4) _int) - (if (system-big-endian?) - (test #x00001212 ptr-ref p _int) - (test #x12120005 ptr-ref p _int)) + (test (if (system-big-endian?) #x00001212 #x12120005) + ptr-ref p _int) (ptr-set! (ptr-add p 4 _int) _int 10) (ptr-set! (ptr-add p 5 _int) _int 11) (ptr-set! (ptr-add p 6 _int) _int 12) - (memmove p 2 _int p 4 _int 3 _int) + (memmove p 2 p 4 3 _int) (test 10 ptr-ref (ptr-add p 2 _int) _int) (test 11 ptr-ref (ptr-add p 3 _int) _int) (test 12 ptr-ref (ptr-add p 4 _int) _int) - (memmove p 6 _short p 8 _byte 12) + (memmove p (* 6 (ctype-sizeof _short)) p 8 12) (test 10 ptr-ref (ptr-add p 2 _int) _int) (test 10 ptr-ref (ptr-add p 3 _int) _int) (test 11 ptr-ref (ptr-add p 4 _int) _int) @@ -174,7 +173,8 @@ (test #f ptr-equal? p (ptr-add p 3)) (test #t ptr-equal? p (ptr-add (ptr-add p 3) -3)) (test #f ptr-equal? #f (ptr-add #f 8)) - (test #t ptr-equal? #f (ptr-add (ptr-add #f 8) -8))) + (test #t ptr-equal? #f (ptr-add (ptr-add #f 8) -8)) + ) (report-errs) diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index 336d2061b5..80e249c6f6 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -1942,20 +1942,39 @@ static Scheme_Object *do_memop(const char *who, int mode, /* mode 0=>memset, 1=>memmove, 2=>memcpy */ { void *src = NULL, *dest = NULL; - long soff = 0, doff = 0, count, v, mult = 1; - int i = 0, j, ch = 0; + long soff = 0, doff = 0, count, v, mult = 0; + int i, j, ch = 0, argc1 = argc; - /* do the optional last ctype multiplier first, to use it later */ - if (SCHEME_CTYPEP(argv[argc-1])) { - mult = ctype_sizeof(argv[argc-1]); + /* arg parsing: last optional ctype, then count, then fill byte for memset, + * then the first and second pointer+offset pair. */ + + /* get the optional last ctype multiplier */ + if (SCHEME_CTYPEP(argv[argc1-1])) { + argc1--; + mult = ctype_sizeof(argv[argc1]); if (mult <= 0) - scheme_wrong_type(who, "non-void-C-type", argc-1, argc, argv); + scheme_wrong_type(who, "non-void-C-type", argc1, argc, argv); } - /* get the two pointers+offsets */ + /* get the count argument */ + argc1--; + if ((!scheme_get_int_val(argv[argc1], &count)) || (count < 0)) + scheme_wrong_type(who, "count as " C_LONG_TYPE_STR, argc1, argc, argv); + if (mult) count *= mult; + + /* get the fill byte for memset */ + if (!mode) { + argc1--; + ch = SCHEME_INTP(argv[argc1]) ? SCHEME_INT_VAL(argv[argc1]) : -1; + if ((ch < 0) || (ch > 255)) + scheme_wrong_type(who, "byte", argc1, argc, argv); + } + + /* get the two pointers + offsets */ + i = 0; for (j=0; j<2; j++) { if (!mode && j==1) break; /* memset needs only a dest argument */ - if (!(i 255)) - scheme_wrong_type(who, "byte", i, argc, argv); - i++; - } - - /* get the count */ - if (!(imemset, 1=>memmove, 2=>memcpy */ { void *src = NULL, *dest = NULL; - long soff = 0, doff = 0, count, v, mult = 1; - int i = 0, j, ch = 0; + long soff = 0, doff = 0, count, v, mult = 0; + int i, j, ch = 0, argc1 = argc; - /* do the optional last ctype multiplier first, to use it later */ - if (SCHEME_CTYPEP(argv[argc-1])) { - mult = ctype_sizeof(argv[argc-1]); + /* arg parsing: last optional ctype, then count, then fill byte for memset, + * then the first and second pointer+offset pair. */ + + /* get the optional last ctype multiplier */ + if (SCHEME_CTYPEP(argv[argc1-1])) { + argc1--; + mult = ctype_sizeof(argv[argc1]); if (mult <= 0) - scheme_wrong_type(who, "non-void-C-type", argc-1, argc, argv); + scheme_wrong_type(who, "non-void-C-type", argc1, argc, argv); } - /* get the two pointers+offsets */ + /* get the count argument */ + argc1--; + if ((!scheme_get_int_val(argv[argc1], &count)) || (count < 0)) + scheme_wrong_type(who, "count as " C_LONG_TYPE_STR, argc1, argc, argv); + if (mult) count *= mult; + + /* get the fill byte for memset */ + if (!mode) { + argc1--; + ch = SCHEME_INTP(argv[argc1]) ? SCHEME_INT_VAL(argv[argc1]) : -1; + if ((ch < 0) || (ch > 255)) + scheme_wrong_type(who, "byte", argc1, argc, argv); + } + + /* get the two pointers + offsets */ + i = 0; for (j=0; j<2; j++) { if (!mode && j==1) break; /* memset needs only a dest argument */ - if (!(i 255)) - scheme_wrong_type(who, "byte", i, argc, argv); - i++; - } - - /* get the count */ - if (!(i