1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-10 20:35:14 +00:00
QB64-PE/source/utilities/file.bas

228 lines
6.7 KiB
QBasic
Raw Normal View History

Create icon.rc file on all platforms, copy ico file into temp Previously, the creation of the icon.rc file was restricted to be Windows only because Windows is the only platform with a use for that file. Unfortunately, this breaks a fundimental assumption about how the QB64 C++ generation works, because we only have one set of `./internal/source` files from which we build all versions of QB64 for all platforms. Due to that, the built version needs to include all files needed by all platforms, regardless of which one is doing the building. So to that end, all platforms should produce the icon.rc, even if it will not be used on that platform. Additionally, the path to the icon file in `icon.rc` is problimatic because it is made into an absolute path. This blocks `qb64.bas` from using `$EXEICON` because the absolute path is not predictable, as the location we create ./internal/source will be different from the location we build ./internal/source. Effectively this means that the `icon.rc` file in `./internal/source` would always be wrong. The solution is to not use an absolute path, with the other option being to have the icon in the same directory as the resource file. This is actually relatively easy to acomplish since icon files are not terribly large and we can simply copy it into the temp directory. Thus, that is what this change does - the specified icon file is copied into the temp directory as `icon.ico`, which allows use to use `icon.ico` in the `icon.rc` file and have it always work regardless of directory. The internal logic was also cleaned up a bit. The creation of these files is no longer Windows specific, and the $EXEICON parsing no longer writes to the `icon.rc` file - rather, the entire thing is generated together, with both the $VERSIONINFo and $EXEICON depending on which were provided.
2022-05-01 02:33:43 +00:00
'
' Duplicates the contents of one file into another
'
' Returns: 0 on success, 1 on error
FUNCTION CopyFile& (sourceFile$, destFile$)
2023-03-23 00:03:28 +00:00
DIM sourceFileNo, destFileNo
Create icon.rc file on all platforms, copy ico file into temp Previously, the creation of the icon.rc file was restricted to be Windows only because Windows is the only platform with a use for that file. Unfortunately, this breaks a fundimental assumption about how the QB64 C++ generation works, because we only have one set of `./internal/source` files from which we build all versions of QB64 for all platforms. Due to that, the built version needs to include all files needed by all platforms, regardless of which one is doing the building. So to that end, all platforms should produce the icon.rc, even if it will not be used on that platform. Additionally, the path to the icon file in `icon.rc` is problimatic because it is made into an absolute path. This blocks `qb64.bas` from using `$EXEICON` because the absolute path is not predictable, as the location we create ./internal/source will be different from the location we build ./internal/source. Effectively this means that the `icon.rc` file in `./internal/source` would always be wrong. The solution is to not use an absolute path, with the other option being to have the icon in the same directory as the resource file. This is actually relatively easy to acomplish since icon files are not terribly large and we can simply copy it into the temp directory. Thus, that is what this change does - the specified icon file is copied into the temp directory as `icon.ico`, which allows use to use `icon.ico` in the `icon.rc` file and have it always work regardless of directory. The internal logic was also cleaned up a bit. The creation of these files is no longer Windows specific, and the $EXEICON parsing no longer writes to the `icon.rc` file - rather, the entire thing is generated together, with both the $VERSIONINFo and $EXEICON depending on which were provided.
2022-05-01 02:33:43 +00:00
DIM fileLength AS _INTEGER64
E = 0
sourceFileNo = FREEFILE
2023-03-23 00:03:28 +00:00
OPEN sourceFile$ FOR BINARY AS #sourceFileNo
IF E = 1 THEN GOTO errorCleanup
Create icon.rc file on all platforms, copy ico file into temp Previously, the creation of the icon.rc file was restricted to be Windows only because Windows is the only platform with a use for that file. Unfortunately, this breaks a fundimental assumption about how the QB64 C++ generation works, because we only have one set of `./internal/source` files from which we build all versions of QB64 for all platforms. Due to that, the built version needs to include all files needed by all platforms, regardless of which one is doing the building. So to that end, all platforms should produce the icon.rc, even if it will not be used on that platform. Additionally, the path to the icon file in `icon.rc` is problimatic because it is made into an absolute path. This blocks `qb64.bas` from using `$EXEICON` because the absolute path is not predictable, as the location we create ./internal/source will be different from the location we build ./internal/source. Effectively this means that the `icon.rc` file in `./internal/source` would always be wrong. The solution is to not use an absolute path, with the other option being to have the icon in the same directory as the resource file. This is actually relatively easy to acomplish since icon files are not terribly large and we can simply copy it into the temp directory. Thus, that is what this change does - the specified icon file is copied into the temp directory as `icon.ico`, which allows use to use `icon.ico` in the `icon.rc` file and have it always work regardless of directory. The internal logic was also cleaned up a bit. The creation of these files is no longer Windows specific, and the $EXEICON parsing no longer writes to the `icon.rc` file - rather, the entire thing is generated together, with both the $VERSIONINFo and $EXEICON depending on which were provided.
2022-05-01 02:33:43 +00:00
fileLength = LOF(sourceFileNo)
destFileNo = FREEFILE
OPEN destFile$ FOR OUTPUT AS #destFileNo: CLOSE #destFileNo 'create and blank any existing file with the dest name.
2023-03-23 00:03:28 +00:00
OPEN destFile$ FOR BINARY AS #destFileNo
IF E = 1 THEN GOTO errorCleanup
Create icon.rc file on all platforms, copy ico file into temp Previously, the creation of the icon.rc file was restricted to be Windows only because Windows is the only platform with a use for that file. Unfortunately, this breaks a fundimental assumption about how the QB64 C++ generation works, because we only have one set of `./internal/source` files from which we build all versions of QB64 for all platforms. Due to that, the built version needs to include all files needed by all platforms, regardless of which one is doing the building. So to that end, all platforms should produce the icon.rc, even if it will not be used on that platform. Additionally, the path to the icon file in `icon.rc` is problimatic because it is made into an absolute path. This blocks `qb64.bas` from using `$EXEICON` because the absolute path is not predictable, as the location we create ./internal/source will be different from the location we build ./internal/source. Effectively this means that the `icon.rc` file in `./internal/source` would always be wrong. The solution is to not use an absolute path, with the other option being to have the icon in the same directory as the resource file. This is actually relatively easy to acomplish since icon files are not terribly large and we can simply copy it into the temp directory. Thus, that is what this change does - the specified icon file is copied into the temp directory as `icon.ico`, which allows use to use `icon.ico` in the `icon.rc` file and have it always work regardless of directory. The internal logic was also cleaned up a bit. The creation of these files is no longer Windows specific, and the $EXEICON parsing no longer writes to the `icon.rc` file - rather, the entire thing is generated together, with both the $VERSIONINFo and $EXEICON depending on which were provided.
2022-05-01 02:33:43 +00:00
' Read the file in one go
buffer$ = SPACE$(fileLength)
GET #sourceFileNo, , buffer$
PUT #destFileNo, , buffer$
2023-03-23 00:03:28 +00:00
errorCleanup:
Create icon.rc file on all platforms, copy ico file into temp Previously, the creation of the icon.rc file was restricted to be Windows only because Windows is the only platform with a use for that file. Unfortunately, this breaks a fundimental assumption about how the QB64 C++ generation works, because we only have one set of `./internal/source` files from which we build all versions of QB64 for all platforms. Due to that, the built version needs to include all files needed by all platforms, regardless of which one is doing the building. So to that end, all platforms should produce the icon.rc, even if it will not be used on that platform. Additionally, the path to the icon file in `icon.rc` is problimatic because it is made into an absolute path. This blocks `qb64.bas` from using `$EXEICON` because the absolute path is not predictable, as the location we create ./internal/source will be different from the location we build ./internal/source. Effectively this means that the `icon.rc` file in `./internal/source` would always be wrong. The solution is to not use an absolute path, with the other option being to have the icon in the same directory as the resource file. This is actually relatively easy to acomplish since icon files are not terribly large and we can simply copy it into the temp directory. Thus, that is what this change does - the specified icon file is copied into the temp directory as `icon.ico`, which allows use to use `icon.ico` in the `icon.rc` file and have it always work regardless of directory. The internal logic was also cleaned up a bit. The creation of these files is no longer Windows specific, and the $EXEICON parsing no longer writes to the `icon.rc` file - rather, the entire thing is generated together, with both the $VERSIONINFo and $EXEICON depending on which were provided.
2022-05-01 02:33:43 +00:00
IF sourceFileNo <> 0 THEN CLOSE #sourceFileNo
IF destFileNo <> 0 THEN CLOSE #destFileNo
CopyFile& = E
END FUNCTION
'
' Convert a file into an C-Array incl. read function and append it
' to the file 'internal\temp\embedded.cpp'
'
' Inputs: sourcefile spec, unique handle (case sensitive)
' Return: 0 = normal embed, 1 = packed embed (DEPENDENCY_ZLIB required)
FUNCTION ConvertFileToCArray% (file$, handle$)
'--- read file contents ---
sff% = FREEFILE
OPEN "B", #sff%, file$
filedata$ = SPACE$(LOF(sff%))
GET #sff%, , filedata$
CLOSE #sff%
'--- try to compress ---
compdata$ = _DEFLATE$(filedata$)
IF LEN(compdata$) < (LEN(filedata$) * 0.8) THEN
tmpfile$ = tmpdir$ + "embed.bin"
OPEN "O", #sff%, tmpfile$: CLOSE #sff%
OPEN "B", #sff%, tmpfile$: PUT #sff%, , compdata$: CLOSE #sff%
packed% = 1
OPEN "B", #sff%, tmpfile$
ELSE
packed% = 0
OPEN "B", #sff%, file$
END IF
'--- init variables ---
fl& = LOF(sff%)
cntL& = INT(fl& / 32)
cntV& = INT(cntL& / 8180)
cntB& = (fl& - (cntL& * 32))
'--- create C-Array ---
dff% = FREEFILE
OPEN "A", #dff%, tmpdir$ + "embedded.cpp"
'--- process LONGs ---
tmpI$ = SPACE$(32)
FOR vc& = 0 TO cntV&
IF vc& = cntV& THEN numL& = (cntL& MOD 8180): ELSE numL& = 8180
PRINT #dff%, "static const uint32_t "; handle$; "L"; LTRIM$(STR$(vc&)); "[] = {"
PRINT #dff%, " "; LTRIM$(STR$(numL& * 8)); ","
FOR z& = 1 TO numL&
GET #sff%, , tmpI$: offI% = 1
tmpO$ = " " + STRING$(88, ","): offO% = 5
DO
tmpL& = CVL(MID$(tmpI$, offI%, 4)): offI% = offI% + 4
MID$(tmpO$, offO%, 10) = "0x" + RIGHT$("00000000" + HEX$(tmpL&), 8)
offO% = offO% + 11
LOOP UNTIL offO% > 92
IF z& < numL& THEN PRINT #dff%, tmpO$: ELSE PRINT #dff%, LEFT$(tmpO$, 91)
NEXT z&
PRINT #dff%, "};"
PRINT #dff%, ""
NEXT vc&
'--- process remaining BYTEs ---
IF cntB& > 0 THEN
PRINT #dff%, "static const uint8_t "; handle$; "B[] = {"
PRINT #dff%, " "; LTRIM$(STR$(cntB&)); ","
PRINT #dff%, " ";
FOR x% = 1 TO cntB&
GET #sff%, , tmpB%%
PRINT #dff%, "0x" + RIGHT$("00" + HEX$(tmpB%%), 2);
IF x% <> 16 THEN
IF x% <> cntB& THEN PRINT #dff%, ",";
ELSE
IF x% <> cntB& THEN
PRINT #dff%, ","
PRINT #dff%, " ";
END IF
END IF
NEXT x%
PRINT #dff%, ""
PRINT #dff%, "};"
PRINT #dff%, ""
END IF
'--- make a read function ---
PRINT #dff%, "qbs *GetArrayData_"; handle$; "(void)"
PRINT #dff%, "{"
PRINT #dff%, " qbs *data = qbs_new("; LTRIM$(STR$(fl&)); ", 1);"
PRINT #dff%, " char *buff = (char*) data -> chr;"
PRINT #dff%, ""
FOR vc& = 0 TO cntV&
PRINT #dff%, " memcpy(buff, &"; handle$; "L"; LTRIM$(STR$(vc&)); "[1], "; handle$; "L"; LTRIM$(STR$(vc&)); "[0] << 2);"
IF vc& < cntV& OR cntB& > 0 THEN
PRINT #dff%, " buff += ("; handle$; "L"; LTRIM$(STR$(vc&)); "[0] << 2);"
END IF
NEXT vc&
IF cntB& > 0 THEN
PRINT #dff%, " memcpy(buff, &"; handle$; "B[1], "; handle$; "B[0]);"
END IF
PRINT #dff%, ""
IF packed% THEN
PRINT #dff%, " return func__inflate(data, "; LTRIM$(STR$(LEN(filedata$))); ", 1);"
ELSE
PRINT #dff%, " return data;"
END IF
PRINT #dff%, "}"
PRINT #dff%, ""
'--- ending ---
CLOSE #dff%
CLOSE #sff%
ConvertFileToCArray% = packed%
END FUNCTION
'
' Splits the filename from its path, and returns the path
'
' Returns: The path, or empty if no path
FUNCTION getfilepath$ (f$)
FOR i = LEN(f$) TO 1 STEP -1
a$ = MID$(f$, i, 1)
IF a$ = "/" OR a$ = "\" THEN
getfilepath$ = LEFT$(f$, i)
EXIT FUNCTION
END IF
NEXT
getfilepath$ = ""
END FUNCTION
'
' Checks if a filename has an extension on the end
'
' Returns: True if provided filename has an extension
FUNCTION FileHasExtension (f$)
FOR i = LEN(f$) TO 1 STEP -1
a = ASC(f$, i)
IF a = 47 OR a = 92 THEN EXIT FOR
IF a = 46 THEN FileHasExtension = -1: EXIT FUNCTION
NEXT
END FUNCTION
'
' Strips the extension off of a filename
'
' Returns: Provided filename without extension on the end
FUNCTION RemoveFileExtension$ (f$)
FOR i = LEN(f$) TO 1 STEP -1
a = ASC(f$, i)
IF a = 47 OR a = 92 THEN EXIT FOR
IF a = 46 THEN RemoveFileExtension$ = LEFT$(f$, i - 1): EXIT FUNCTION
NEXT
RemoveFileExtension$ = f$
END FUNCTION
'
' Returns the extension on the end of a file name
'
' Returns "" if there is no extension
'
FUNCTION GetFileExtension$ (f$)
FOR i = LEN(f$) TO 1 STEP -1
a = ASC(f$, i)
IF a = 47 OR a = 92 THEN EXIT FOR
IF a = 46 THEN GetFileExtension$ = MID$(f$, i + 1): EXIT FUNCTION
NEXT
GetFileExtension$ = ""
END FUNCTION
'
' Fixes the provided filename and path to use the correct path separator
'
SUB PATH_SLASH_CORRECT (a$)
IF os$ = "WIN" THEN
FOR x = 1 TO LEN(a$)
IF ASC(a$, x) = 47 THEN ASC(a$, x) = 92
NEXT
ELSE
FOR x = 1 TO LEN(a$)
IF ASC(a$, x) = 92 THEN ASC(a$, x) = 47
NEXT
END IF
END SUB
2023-03-23 00:03:28 +00:00
' Return a pathname where all "\" are correctly escaped
FUNCTION GetEscapedPath$ (path_name AS STRING)
DIM buf AS STRING, z AS _UNSIGNED LONG, a AS _UNSIGNED _BYTE
FOR z = 1 TO LEN(path_name)
a = ASC(path_name, z)
buf = buf + CHR$(a)
IF a = 92 THEN buf = buf + "\"
NEXT
GetEscapedPath = buf
END FUNCTION
' Adds a trailing \ or / to a directory name if needed
2023-03-23 00:03:28 +00:00
FUNCTION FixDirectoryName$ (dir_name AS STRING)
IF LEN(dir_name) > 0 AND RIGHT$(dir_name, 1) <> pathsep$ THEN
FixDirectoryName = dir_name + pathsep$
ELSE
FixDirectoryName = dir_name
END IF
END FUNCTION