~ chicken-core (chicken-5) 733f1c8fb843824540d154b86a785a21615a72a3
commit 733f1c8fb843824540d154b86a785a21615a72a3 Author: Evan Hanson <evhan@foldling.org> AuthorDate: Fri May 19 22:11:03 2017 +1200 Commit: Peter Bex <peter@more-magic.net> CommitDate: Sat May 27 13:14:55 2017 +0200 Drop files.scm This was only left in place to ease the transition from the "files" and "posix" units to separate "file" and "file.posix" modules. Now that some of the smoke has cleared from other refactoring, we can finish the rename and drop files.scm. Signed-off-by: Peter Bex <peter@more-magic.net> diff --git a/README b/README index 2047a8de..00eca60e 100644 --- a/README +++ b/README @@ -295,7 +295,6 @@ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ | | |-- chicken.expand.import.so | | |-- chicken.file.import.so | | |-- chicken.file.posix.import.so - | | |-- chicken.files.import.so | | |-- chicken.fixnum.import.so | | |-- chicken.flonum.import.so | | |-- chicken.foreign.import.so diff --git a/chicken-install.scm b/chicken-install.scm index 0e56b0e2..4ac64ea4 100644 --- a/chicken-install.scm +++ b/chicken-install.scm @@ -32,7 +32,7 @@ (import (chicken foreign)) (import (chicken data-structures)) (import (chicken keyword)) -(import (chicken files)) +(import (chicken file)) (import (chicken format)) (import (chicken irregex)) (import (chicken tcp)) diff --git a/chicken-status.scm b/chicken-status.scm index 2fb54c53..3b957ae6 100644 --- a/chicken-status.scm +++ b/chicken-status.scm @@ -28,7 +28,7 @@ (import (scheme)) (import (chicken)) (import (chicken data-structures) - (chicken files) + (chicken file) (chicken foreign) (chicken format) (chicken irregex) diff --git a/chicken-uninstall.scm b/chicken-uninstall.scm index d9c79250..df8fa01e 100644 --- a/chicken-uninstall.scm +++ b/chicken-uninstall.scm @@ -29,7 +29,7 @@ (import (scheme) (chicken)) (import (chicken data-structures) - (chicken files) + (chicken file) (chicken foreign) (chicken io) (chicken format) diff --git a/defaults.make b/defaults.make index a7fa5e91..c9789f6e 100644 --- a/defaults.make +++ b/defaults.make @@ -271,7 +271,7 @@ DYNAMIC_CHICKEN_IMPORT_LIBRARIES = bitwise errno file.posix \ process-context random time time.posix DYNAMIC_CHICKEN_COMPILER_IMPORT_LIBRARIES = user-pass DYNAMIC_CHICKEN_UNIT_IMPORT_LIBRARIES = continuation data-structures \ - eval expand file files internal irregex lolevel pathname port \ + eval expand file internal irregex lolevel pathname port \ read-syntax repl tcp # targets diff --git a/distribution/manifest b/distribution/manifest index 69b81782..14a618d4 100644 --- a/distribution/manifest +++ b/distribution/manifest @@ -25,7 +25,6 @@ dbg-stub.c debugger-client.c port.c file.c -files.c extras.c internal.c library.c @@ -78,7 +77,6 @@ data-structures.scm debugger-client.scm port.scm file.scm -files.scm chicken-bug.mdoc chicken-bug.scm chicken-bug.c @@ -285,8 +283,6 @@ chicken.file.import.scm chicken.file.import.c chicken.file.posix.import.scm chicken.file.posix.import.c -chicken.files.import.scm -chicken.files.import.c chicken.fixnum.import.scm chicken.fixnum.import.c chicken.flonum.import.scm diff --git a/file.scm b/file.scm index 4eef581c..68d9fc4b 100644 --- a/file.scm +++ b/file.scm @@ -35,9 +35,20 @@ (declare (unit file) - (uses files posix) + (uses extras pathname posix) (fixnum) - (disable-interrupts)) + (disable-interrupts) + (foreign-declare #<<EOF +#include <errno.h> + +#ifndef _WIN32 +# include <sys/stat.h> +# define C_mkdir(str) C_fix(mkdir(C_c_string(str), S_IRWXU | S_IRWXG | S_IRWXO)) +#else +# define C_mkdir(str) C_fix(mkdir(C_c_string(str))) +#endif +EOF +)) (module chicken.file (block-device? @@ -71,4 +82,144 @@ socket? symbolic-link?) -(import chicken chicken.files chicken.posix)) +(import chicken scheme + chicken.foreign + chicken.io + chicken.pathname + chicken.posix) + +(include "common-declarations.scm") + +(define-foreign-variable strerror c-string "strerror(errno)") + + +;;; Like `delete-file', but does nothing if the file doesn't exist: + +(define delete-file* + (lambda (file) + (and (file-exists? file) (delete-file file)))) + + +;;; file-copy and file-move : they do what you'd think. + +(define (file-copy origfile newfile #!optional (clobber #f) (blocksize 1024)) + (##sys#check-string origfile 'file-copy) + (##sys#check-string newfile 'file-copy) + (##sys#check-number blocksize 'file-copy) + (unless (and (integer? blocksize) (> blocksize 0)) + (##sys#error + 'file-copy + "invalid blocksize given: not a positive integer" + blocksize)) + (and (file-exists? newfile) + (or clobber + (##sys#error + 'file-copy + "newfile exists but clobber is false" + newfile))) + (when (directory-exists? origfile) + (##sys#error 'file-copy "can not copy directories" origfile)) + (let* ((i (open-input-file origfile #:binary)) + (o (open-output-file newfile #:binary)) + (s (make-string blocksize))) + (let loop ((d (read-string! blocksize s i)) + (l 0)) + (if (fx= 0 d) + (begin + (close-input-port i) + (close-output-port o) + l) + (begin + (write-string s d o) + (loop (read-string! blocksize s i) (fx+ d l))))))) + +(define (file-move origfile newfile #!optional (clobber #f) (blocksize 1024)) + (##sys#check-string origfile 'file-move) + (##sys#check-string newfile 'file-move) + (##sys#check-number blocksize 'file-move) + (unless (and (integer? blocksize) (> blocksize 0)) + (##sys#error + 'file-move + "invalid blocksize given: not a positive integer" + blocksize)) + (when (directory-exists? origfile) + (##sys#error 'file-move "can not move directories" origfile)) + (and (file-exists? newfile) + (or clobber + (##sys#error + 'file-move + "newfile exists but clobber is false" + newfile))) + (let* ((i (open-input-file origfile #:binary)) + (o (open-output-file newfile #:binary)) + (s (make-string blocksize))) + (let loop ((d (read-string! blocksize s i)) + (l 0)) + (if (fx= 0 d) + (begin + (close-input-port i) + (close-output-port o) + (delete-file origfile) + l) + (begin + (write-string s d o) + (loop (read-string! blocksize s i) (fx+ d l))))))) + + +;;; Temporary file creation: + +(define create-temporary-file) +(define create-temporary-directory) + +(let ((temp #f) + (temp-prefix "temp") + (string-append string-append)) + (define (tempdir) + (or temp + (let ((tmp + (or (get-environment-variable "TMPDIR") + (get-environment-variable "TEMP") + (get-environment-variable "TMP") + "/tmp"))) + (set! temp tmp) + tmp))) + (set! create-temporary-file + (lambda (#!optional (ext "tmp")) + (##sys#check-string ext 'create-temporary-file) + (let loop () + (let* ((n (##core#inline "C_random_fixnum" #x10000)) + (getpid (foreign-lambda int "C_getpid")) + (pn (make-pathname + (tempdir) + (string-append + temp-prefix + (number->string n 16) + "." + (##sys#number->string (getpid))) + ext))) + (if (file-exists? pn) + (loop) + (call-with-output-file pn (lambda (p) pn))))))) + (set! create-temporary-directory + (lambda () + (let loop () + (let* ((n (##core#inline "C_random_fixnum" #x10000)) + (getpid (foreign-lambda int "C_getpid")) + (pn (make-pathname + (tempdir) + (string-append + temp-prefix + (number->string n 16) + "." + (##sys#number->string (getpid)))))) + (if (file-exists? pn) + (loop) + (let ((r (##core#inline "C_mkdir" (##sys#make-c-string pn 'create-temporary-directory)))) + (if (eq? r 0) + pn + (##sys#signal-hook + #:file-error 'create-temporary-directory + (##sys#string-append "cannot create temporary directory - " strerror) + pn))))))))) + +) diff --git a/files.scm b/files.scm deleted file mode 100644 index c071ad0a..00000000 --- a/files.scm +++ /dev/null @@ -1,196 +0,0 @@ -;;;; files.scm - File operations -; -; Copyright (c) 2008-2017, The CHICKEN Team -; Copyright (c) 2000-2007, Felix L. Winkelmann -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions -; are met: -; -; Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; -; Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in -; the documentation and/or other materials provided with the -; distribution. -; -; Neither the name of the author nor the names of its contributors -; may be used to endorse or promote products derived from this -; software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -; COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -; OF THE POSSIBILITY OF SUCH DAMAGE. - - -(declare - (unit files) - (uses extras pathname) - (fixnum) - (disable-interrupts) - (foreign-declare #<<EOF -#include <errno.h> - -#ifndef _WIN32 -# include <sys/stat.h> -# define C_mkdir(str) C_fix(mkdir(C_c_string(str), S_IRWXU | S_IRWXG | S_IRWXO)) -#else -# define C_mkdir(str) C_fix(mkdir(C_c_string(str))) -#endif -EOF -)) - -(module chicken.files - (delete-file* file-copy file-move - create-temporary-directory - create-temporary-file) - -(import scheme chicken) -(import chicken.foreign - chicken.io - chicken.pathname) - -(include "common-declarations.scm") - - -(define-foreign-variable strerror c-string "strerror(errno)") - - -;;; Like `delete-file', but does nothing if the file doesn't exist: - -(define delete-file* - (lambda (file) - (and (file-exists? file) (delete-file file)) ) ) - -;;; file-copy and file-move : they do what you'd think. - -(define (file-copy origfile newfile #!optional (clobber #f) (blocksize 1024)) - (##sys#check-string origfile 'file-copy) - (##sys#check-string newfile 'file-copy) - (##sys#check-number blocksize 'file-copy) - (unless (and (integer? blocksize) (> blocksize 0)) - (##sys#error - 'file-copy - "invalid blocksize given: not a positive integer" - blocksize)) - (and (file-exists? newfile) - (or clobber - (##sys#error - 'file-copy - "newfile exists but clobber is false" - newfile))) - (when (directory-exists? origfile) - (##sys#error 'file-copy "can not copy directories" origfile)) - (let* ((i (open-input-file origfile #:binary)) - (o (open-output-file newfile #:binary)) - (s (make-string blocksize))) - (let loop ((d (read-string! blocksize s i)) - (l 0)) - (if (fx= 0 d) - (begin - (close-input-port i) - (close-output-port o) - l) - (begin - (write-string s d o) - (loop (read-string! blocksize s i) (fx+ d l))))))) - -(define (file-move origfile newfile #!optional (clobber #f) (blocksize 1024)) - (##sys#check-string origfile 'file-move) - (##sys#check-string newfile 'file-move) - (##sys#check-number blocksize 'file-move) - (unless (and (integer? blocksize) (> blocksize 0)) - (##sys#error - 'file-move - "invalid blocksize given: not a positive integer" - blocksize)) - (when (directory-exists? origfile) - (##sys#error 'file-move "can not move directories" origfile)) - (and (file-exists? newfile) - (or clobber - (##sys#error - 'file-move - "newfile exists but clobber is false" - newfile))) - (let* ((i (open-input-file origfile #:binary)) - (o (open-output-file newfile #:binary)) - (s (make-string blocksize))) - (let loop ((d (read-string! blocksize s i)) - (l 0)) - (if (fx= 0 d) - (begin - (close-input-port i) - (close-output-port o) - (delete-file origfile) - l) - (begin - (write-string s d o) - (loop (read-string! blocksize s i) (fx+ d l))))))) - - -;;; Temporary file creation: - -(define create-temporary-file) -(define create-temporary-directory) - -(let ((temp #f) - (temp-prefix "temp") - (string-append string-append)) - (define (tempdir) - (or temp - (let ((tmp - (or (get-environment-variable "TMPDIR") - (get-environment-variable "TEMP") - (get-environment-variable "TMP") - "/tmp"))) - (set! temp tmp) - tmp))) - (set! create-temporary-file - (lambda (#!optional (ext "tmp")) - (##sys#check-string ext 'create-temporary-file) - (let loop () - (let* ((n (##core#inline "C_random_fixnum" #x10000)) - (getpid (foreign-lambda int "C_getpid")) - (pn (make-pathname - (tempdir) - (string-append - temp-prefix - (number->string n 16) - "." - (##sys#number->string (getpid))) - ext)) ) - (if (file-exists? pn) - (loop) - (call-with-output-file pn (lambda (p) pn)) ) ) ) ) ) - (set! create-temporary-directory - (lambda () - (let loop () - (let* ((n (##core#inline "C_random_fixnum" #x10000)) - (getpid (foreign-lambda int "C_getpid")) - (pn (make-pathname - (tempdir) - (string-append - temp-prefix - (number->string n 16) - "." - (##sys#number->string (getpid)))))) - (if (file-exists? pn) - (loop) - (let ((r (##core#inline "C_mkdir" (##sys#make-c-string pn 'create-temporary-directory)))) - (if (eq? r 0) - pn - (##sys#signal-hook - #:file-error 'create-temporary-directory - (##sys#string-append "cannot create temporary directory - " strerror) - pn)))))))))) diff --git a/modules.scm b/modules.scm index 4f90cb11..a5680b2a 100644 --- a/modules.scm +++ b/modules.scm @@ -954,7 +954,6 @@ (##sys#register-module-alias 'eval 'chicken.eval) (##sys#register-module-alias 'expand 'chicken.expand) (##sys#register-module-alias 'file 'chicken.file) -(##sys#register-module-alias 'files 'chicken.files) (##sys#register-module-alias 'fixnum 'chicken.fixnum) (##sys#register-module-alias 'flonum 'chicken.flonum) (##sys#register-module-alias 'foreign 'chicken.foreign) diff --git a/posix.scm b/posix.scm index 96c932a8..63729d3f 100644 --- a/posix.scm +++ b/posix.scm @@ -35,7 +35,7 @@ (declare (unit posix) - (uses scheduler irregex pathname extras files port lolevel) + (uses scheduler irregex pathname extras port lolevel) (disable-interrupts) (not inline ##sys#interrupt-hook ##sys#user-interrupt-hook)) diff --git a/rules.make b/rules.make index 3a1e3425..35a9132f 100644 --- a/rules.make +++ b/rules.make @@ -35,9 +35,9 @@ VPATH=$(SRCDIR) LIBCHICKEN_SCHEME_OBJECTS_1 = \ library eval read-syntax repl data-structures pathname port file \ - files extras lolevel tcp srfi-4 continuation $(POSIXFILE) \ - internal irregex scheduler debugger-client profiler stub expand \ - modules chicken-syntax chicken-ffi-syntax build-version + extras lolevel tcp srfi-4 continuation $(POSIXFILE) internal \ + irregex scheduler debugger-client profiler stub expand modules \ + chicken-syntax chicken-ffi-syntax build-version LIBCHICKEN_OBJECTS_1 = $(LIBCHICKEN_SCHEME_OBJECTS_1) runtime LIBCHICKEN_SHARED_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=$(O)) LIBCHICKEN_STATIC_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=-static$(O)) @@ -605,7 +605,7 @@ support.c: support.scm mini-srfi-1.scm \ chicken.condition.import.scm \ chicken.data-structures.import.scm \ chicken.expand.import.scm \ - chicken.files.import.scm \ + chicken.file.import.scm \ chicken.foreign.import.scm \ chicken.format.import.scm \ chicken.internal.import.scm \ @@ -658,6 +658,7 @@ chicken-profile.c: chicken-profile.scm \ chicken.posix.import.scm chicken-status.c: chicken-status.scm \ chicken.data-structures.import.scm \ + chicken.file.import.scm \ chicken.foreign.import.scm \ chicken.format.import.scm \ chicken.irregex.import.scm \ @@ -668,7 +669,7 @@ chicken-status.c: chicken-status.scm \ chicken-install.c: chicken-install.scm \ chicken.condition.import.scm \ chicken.data-structures.import.scm \ - chicken.files.import.scm \ + chicken.file.import.scm \ chicken.foreign.import.scm \ chicken.format.import.scm \ chicken.io.import.scm \ @@ -680,6 +681,7 @@ chicken-install.c: chicken-install.scm \ chicken.tcp.import.scm chicken-uninstall.c: chicken-uninstall.scm \ chicken.data-structures.import.scm \ + chicken.file.import.scm \ chicken.foreign.import.scm \ chicken.format.import.scm \ chicken.irregex.import.scm \ @@ -735,14 +737,10 @@ eval.c: eval.scm \ repl.c: repl.scm \ chicken.eval.import.scm file.c: file.scm \ - chicken.files.import.scm \ - chicken.posix.import.scm -files.c: files.scm \ - chicken.data-structures.import.scm \ chicken.io.import.scm \ chicken.foreign.import.scm \ - chicken.irregex.import.scm \ - chicken.pathname.import.scm + chicken.pathname.import.scm \ + chicken.posix.import.scm lolevel.c: lolevel.scm \ chicken.foreign.import.scm pathname.c: pathname.scm \ @@ -829,8 +827,6 @@ port.c: $(SRCDIR)port.scm $(SRCDIR)common-declarations.scm $(bootstrap-lib) -emit-import-library chicken.port file.c: $(SRCDIR)file.scm $(SRCDIR)common-declarations.scm $(bootstrap-lib) -emit-import-library chicken.file -files.c: $(SRCDIR)files.scm $(SRCDIR)common-declarations.scm - $(bootstrap-lib) -emit-import-library chicken.files lolevel.c: $(SRCDIR)lolevel.scm $(SRCDIR)common-declarations.scm $(bootstrap-lib) \ -emit-import-library chicken.locative \ diff --git a/scripts/make-wrapper.scm b/scripts/make-wrapper.scm index e1a0daa5..4b39136a 100644 --- a/scripts/make-wrapper.scm +++ b/scripts/make-wrapper.scm @@ -3,7 +3,7 @@ ; usage: csi -s make-wrapper.scm NAME BINPATH -(use extras files) +(use pathname) (let* ((args (command-line-arguments)) diff --git a/scripts/makedist.scm b/scripts/makedist.scm index 4cfd52d3..3ae9e899 100644 --- a/scripts/makedist.scm +++ b/scripts/makedist.scm @@ -1,7 +1,8 @@ ;;;; makedist.scm - Make distribution tarballs -(use data-structures files irregex posix +(use data-structures irregex posix + (chicken file) (chicken format) (chicken io) (chicken pathname) diff --git a/scripts/mini-salmonella.scm b/scripts/mini-salmonella.scm index 39568f96..211aa75a 100644 --- a/scripts/mini-salmonella.scm +++ b/scripts/mini-salmonella.scm @@ -4,7 +4,7 @@ (module mini-salmonella () (import scheme chicken) -(use posix files extras data-structures setup-api (chicken process)) +(use posix file extras data-structures setup-api (chicken process)) (define (usage code) (print "usage: mini-salmonella [-h] [-test] [-debug] [-download] [-trunk] EGGDIR [PREFIX]") diff --git a/scripts/setversion b/scripts/setversion index 923f8a5e..97bb49e8 100755 --- a/scripts/setversion +++ b/scripts/setversion @@ -3,7 +3,7 @@ exec csi -s "$0" "$@" |# -(use data-structures files format io irregex (chicken process)) +(use data-structures file format io irregex (chicken process)) (define buildversion (with-input-from-file "buildversion" read-line)) diff --git a/support.scm b/support.scm index 29e867e2..2c04d2e0 100644 --- a/support.scm +++ b/support.scm @@ -27,7 +27,7 @@ (declare (unit support) (not inline ##sys#user-read-hook) ; XXX: Is this needed? - (uses data-structures extras files internal pathname port)) + (uses data-structures extras file internal pathname port)) (module chicken.compiler.support (compiler-cleanup-hook bomb collected-debugging-output debugging @@ -80,7 +80,7 @@ chicken.condition chicken.data-structures chicken.expand - chicken.files + chicken.file chicken.foreign chicken.format chicken.internal diff --git a/tests/port-tests.scm b/tests/port-tests.scm index 463e31e6..9211bd7f 100644 --- a/tests/port-tests.scm +++ b/tests/port-tests.scm @@ -1,4 +1,4 @@ -(require-extension data-structures files flonum format io port posix srfi-4 tcp) +(require-extension data-structures file flonum format io port posix srfi-4 tcp) (include "test.scm") (test-begin) diff --git a/tests/posix-tests.scm b/tests/posix-tests.scm index 83317848..3063f47c 100644 --- a/tests/posix-tests.scm +++ b/tests/posix-tests.scm @@ -1,5 +1,5 @@ (import (chicken pathname) - (chicken files) + (chicken file) (chicken platform) (chicken posix) (chicken lolevel)) diff --git a/tests/reexport-tests.scm b/tests/reexport-tests.scm index 6109c3ae..025c853f 100644 --- a/tests/reexport-tests.scm +++ b/tests/reexport-tests.scm @@ -29,7 +29,7 @@ (compound-module big-chicken - chicken port files pretty-print data-structures) + chicken port file pretty-print data-structures) (module m3 () (import scheme big-chicken) diff --git a/types.db b/types.db index 604c2382..3f389748 100644 --- a/types.db +++ b/types.db @@ -1595,13 +1595,13 @@ (chicken.random#random (#(procedure #:clean #:enforce) chicken.random#random (fixnum) fixnum)) (chicken.random#randomize (#(procedure #:clean #:enforce) chicken.random#randomize (#!optional fixnum) undefined)) -;; files +;; file -(chicken.files#create-temporary-directory (#(procedure #:clean #:enforce) chicken.files#create-temporary-directory () string)) -(chicken.files#create-temporary-file (#(procedure #:clean #:enforce) chicken.files#create-temporary-file (#!optional string) string)) -(chicken.files#delete-file* (#(procedure #:clean #:enforce) chicken.files#delete-file* (string) *)) -(chicken.files#file-copy (#(procedure #:clean #:enforce) chicken.files#file-copy (string string #!optional * fixnum) fixnum)) -(chicken.files#file-move (#(procedure #:clean #:enforce) chicken.files#file-move (string string #!optional * fixnum) fixnum)) +(chicken.file#create-temporary-directory (#(procedure #:clean #:enforce) chicken.file#create-temporary-directory () string)) +(chicken.file#create-temporary-file (#(procedure #:clean #:enforce) chicken.file#create-temporary-file (#!optional string) string)) +(chicken.file#delete-file* (#(procedure #:clean #:enforce) chicken.file#delete-file* (string) *)) +(chicken.file#file-copy (#(procedure #:clean #:enforce) chicken.file#file-copy (string string #!optional * fixnum) fixnum)) +(chicken.file#file-move (#(procedure #:clean #:enforce) chicken.file#file-move (string string #!optional * fixnum) fixnum)) ;; pathnameTrap