Skip to content

Commit 1e08d9d

Browse files
committed
Minor updates and fixes.
1 parent 5053274 commit 1e08d9d

File tree

6 files changed

+68
-63
lines changed

6 files changed

+68
-63
lines changed

Makefile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,34 @@ IMAP = imap
2222
SMTP = smtp
2323
VERSION = version
2424

25-
.PHONY: all clean dict download gopher http imap smtp version
25+
.PHONY: all clean
2626

27-
all: $(TARGET)
27+
all: $(TARGET) $(DICT) $(DOWNLOAD) $(GOPHER) $(HTTP) $(IMAP) $(SMTP) $(VERSION)
2828

2929
$(TARGET):
3030
$(CC) $(CFLAGS) -c src/curlv.c
3131
$(FC) $(FFLAGS) -c src/curl.f90
3232
$(AR) $(ARFLAGS) $(TARGET) curl.o curlv.o
3333

34-
dict: $(TARGET)
34+
$(DICT): $(TARGET)
3535
$(FC) $(FFLAGS) $(LDFLAGS) -o $(DICT) examples/dict/dict.f90 $(TARGET) $(LDLIBS)
3636

37-
download: $(TARGET)
37+
$(DOWNLOAD): $(TARGET)
3838
$(FC) $(FFLAGS) $(LDFLAGS) -o $(DOWNLOAD) examples/download/download.f90 $(TARGET) $(LDLIBS)
3939

40-
gopher: $(TARGET)
40+
$(GOPHER): $(TARGET)
4141
$(FC) $(FFLAGS) $(LDFLAGS) -o $(GOPHER) examples/gopher/gopher.f90 $(TARGET) $(LDLIBS)
4242

43-
http: $(TARGET)
43+
$(HTTP): $(TARGET)
4444
$(FC) $(FFLAGS) $(LDFLAGS) -o $(HTTP) examples/http/http.f90 $(TARGET) $(LDLIBS)
4545

46-
imap: $(TARGET)
46+
$(IMAP): $(TARGET)
4747
$(FC) $(FFLAGS) $(LDFLAGS) -o $(IMAP) examples/imap/imap.f90 $(TARGET) $(LDLIBS)
4848

49-
smtp: $(TARGET)
49+
$(SMTP): $(TARGET)
5050
$(FC) $(FFLAGS) $(LDFLAGS) -o $(SMTP) examples/smtp/smtp.f90 $(TARGET) $(LDLIBS)
5151

52-
version: $(TARGET)
52+
$(VERSION): $(TARGET)
5353
$(FC) $(FFLAGS) $(LDFLAGS) -o $(VERSION) examples/version/version.f90 $(TARGET) $(LDLIBS)
5454

5555
clean:

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ This projects supports the Fortran Package Manager
7171
run:
7272

7373
```
74-
$ fpm build
74+
$ fpm build --profile release
7575
```
7676

7777
The example applications are available with the ``fpm run --example`` command.
@@ -80,7 +80,7 @@ You can use ``fortran-curl`` in your *fpm* projects with
8080

8181
```toml
8282
[dependencies]
83-
fortran-curl.git = "https://interkosmos/fortran-curl.git"
83+
fortran-curl = { git = "https://github.com/interkosmos/fortran-curl.git" }
8484
```
8585

8686
## Licence

examples/download/download.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ function response_callback(ptr, size, nmemb, data) bind(c)
4646
position = 'append', &
4747
status = 'unknown')
4848
if (rc /= 0) return
49-
write (fu) chunk
49+
write (fu, iostat=rc) chunk
5050
close (fu)
51+
if (rc /= 0) return
5152

52-
deallocate (chunk)
5353
response_callback = nmemb
5454
end function response_callback
5555
end module callback_download

examples/http/http.f90

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ module callback_http
1313
integer(kind=8), parameter, public :: MAX_SIZE = 4096
1414

1515
type, public :: response_type
16-
character(len=MAX_SIZE) :: content
17-
integer(kind=8) :: size
16+
character(len=:), allocatable :: body
1817
end type response_type
1918
contains
2019
! static size_t callback(char *ptr, size_t size, size_t nmemb, void *data)
21-
function response_callback(ptr, size, nmemb, data) bind(c)
20+
function response_callback(ptr, size, nmemb, client_data) bind(c)
2221
!! Callback function for `CURLOPT_WRITEFUNCTION` that appends the
2322
!! response chunk `ptr` to the given `data` of type `response_type`.
2423
!!
@@ -28,35 +27,28 @@ function response_callback(ptr, size, nmemb, data) bind(c)
2827
type(c_ptr), intent(in), value :: ptr !! C pointer to a chunk of the response.
2928
integer(kind=c_size_t), intent(in), value :: size !! Always 1.
3029
integer(kind=c_size_t), intent(in), value :: nmemb !! Size of the response chunk.
31-
type(c_ptr), intent(in), value :: data !! C pointer to argument passed by caller.
30+
type(c_ptr), intent(in), value :: client_data !! C pointer to argument passed by caller.
3231
integer(kind=c_size_t) :: response_callback !! Function return value.
3332
type(response_type), pointer :: response !! Stores response.
34-
character(len=:), allocatable :: tmp
35-
integer(kind=8) :: i, j
33+
character(len=:), allocatable :: buf
3634

3735
response_callback = int(0, kind=c_size_t)
3836

37+
! Are the passed C pointers associated?
3938
if (.not. c_associated(ptr)) return
40-
if (.not. c_associated(data)) return
39+
if (.not. c_associated(client_data)) return
4140

42-
call c_f_str_ptr(ptr, tmp, nmemb)
43-
call c_f_pointer(data, response)
41+
! Convert C pointer to Fortran pointer.
42+
call c_f_pointer(client_data, response)
43+
if (.not. allocated(response%body)) response%body = ''
4444

45-
if (response%size == 0) then
46-
response%content = tmp
47-
else
48-
i = response%size + 1
49-
j = i + nmemb
45+
! Convert C pointer to Fortran allocatable character.
46+
call c_f_str_ptr(ptr, buf, nmemb)
47+
if (.not. allocated(buf)) return
48+
response%body = response%body // buf
49+
deallocate (buf)
5050

51-
if (i > MAX_SIZE) return
52-
if (j > MAX_SIZE) j = MAX_SIZE
53-
54-
response%content(i:j) = tmp
55-
end if
56-
57-
response%size = response%size + nmemb
58-
59-
deallocate (tmp)
51+
! Return number of received bytes.
6052
response_callback = nmemb
6153
end function response_callback
6254
end module callback_http
@@ -90,12 +82,15 @@ program main
9082
rc = curl_easy_setopt(curl_ptr, CURLOPT_WRITEDATA, c_loc(response))
9183

9284
! Send request.
93-
if (curl_easy_perform(curl_ptr) /= CURLE_OK) then
85+
rc = curl_easy_perform(curl_ptr)
86+
call curl_easy_cleanup(curl_ptr)
87+
88+
if (rc /= CURLE_OK) then
9489
print '(a)', 'Error: curl_easy_perform() failed'
90+
stop
9591
end if
9692

97-
call curl_easy_cleanup(curl_ptr)
98-
9993
! Output response.
100-
print '(a)', trim(response%content)
94+
if (allocated(response%body)) &
95+
print '(a)', response%body
10196
end program main

fpm.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "fortran-curl"
2-
version = "0.1.1"
2+
version = "0.1.2"
33
license = "ISC"
44
author = "Philipp Engel"
55
maintainer = "@interkosmos"

src/curl.f90

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,9 @@
55
! Author: Philipp Engel
66
! Licence: ISC
77
module curl
8-
use, intrinsic :: iso_c_binding, only: c_associated, c_char, c_f_pointer, c_funptr, &
9-
c_int, c_int64_t, c_loc, c_long, c_ptr, c_size_t
8+
use, intrinsic :: iso_c_binding
109
implicit none
1110

12-
public :: c_f_str_ptr
13-
14-
public :: curl_easy_init
15-
public :: curl_easy_perform
16-
public :: curl_easy_cleanup
17-
public :: curl_easy_setopt
18-
public :: curl_easy_setopt_c_ptr
19-
public :: curl_easy_setopt_c_funptr
20-
public :: curl_slist_append
21-
public :: curl_slist_free_all
22-
public :: curl_version_info
23-
public :: curl_version_now
24-
25-
private :: curl_easy_setopt_char
26-
private :: curl_easy_setopt_fptr
27-
private :: curl_easy_setopt_int
28-
private :: curl_easy_setopt_long
29-
private :: curl_easy_setopt_ptr
30-
3111
integer(kind=c_int), parameter :: CURLOPTTYPE_LONG = 0
3212
integer(kind=c_int), parameter :: CURLOPTTYPE_OBJECTPOINT = 10000
3313
integer(kind=c_int), parameter :: CURLOPTTYPE_STRINGPOINT = 10000
@@ -394,19 +374,22 @@ module curl
394374
! CURL *curl_easy_init(void)
395375
function curl_easy_init() bind(c, name='curl_easy_init')
396376
import :: c_ptr
377+
implicit none
397378
type(c_ptr) :: curl_easy_init
398379
end function curl_easy_init
399380

400381
! CURLcode curl_easy_perform(CURL *curl)
401382
function curl_easy_perform(curl) bind(c, name='curl_easy_perform')
402383
import :: c_int, c_ptr
384+
implicit none
403385
type(c_ptr), intent(in), value :: curl
404386
integer(kind=c_int) :: curl_easy_perform
405387
end function curl_easy_perform
406388

407389
! CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)
408390
function curl_easy_setopt_c_ptr(curl, option, parameter) bind(c, name='curl_easy_setopt')
409391
import :: c_int, c_ptr
392+
implicit none
410393
type(c_ptr), intent(in), value :: curl
411394
integer(kind=c_int), intent(in), value :: option
412395
type(c_ptr), intent(in), value :: parameter
@@ -416,6 +399,7 @@ end function curl_easy_setopt_c_ptr
416399
! CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)
417400
function curl_easy_setopt_c_funptr(curl, option, parameter) bind(c, name='curl_easy_setopt')
418401
import :: c_funptr, c_int, c_ptr
402+
implicit none
419403
type(c_ptr), intent(in), value :: curl
420404
integer(kind=c_int), intent(in), value :: option
421405
type(c_funptr), intent(in), value :: parameter
@@ -425,6 +409,7 @@ end function curl_easy_setopt_c_funptr
425409
! struct curl_slist *curl_slist_append(struct curl_slist *list, const char *string)
426410
function curl_slist_append(list, string) bind(c, name='curl_slist_append')
427411
import :: c_char, c_ptr
412+
implicit none
428413
type(c_ptr), intent(in), value :: list
429414
character(kind=c_char), intent(in) :: string
430415
type(c_ptr) :: curl_slist_append
@@ -433,19 +418,22 @@ end function curl_slist_append
433418
! curl_version_info_data *curl_version_info(CURLversion age)
434419
function curl_version_info_(age) bind(c, name='curl_version_info')
435420
import :: c_int, c_ptr
421+
implicit none
436422
integer(kind=c_int), intent(in), value :: age
437423
type(c_ptr) :: curl_version_info_
438424
end function curl_version_info_
439425

440426
! void curl_easy_cleanup(CURL *curl)
441427
subroutine curl_easy_cleanup(curl) bind(c, name='curl_easy_cleanup')
442428
import :: c_ptr
429+
implicit none
443430
type(c_ptr), intent(in), value :: curl
444431
end subroutine curl_easy_cleanup
445432

446433
! void curl_slist_free_all(struct curl_slist *list)
447434
subroutine curl_slist_free_all(list) bind(c, name='curl_slist_free_all')
448435
import :: c_ptr
436+
implicit none
449437
type(c_ptr), intent(in), value :: list
450438
end subroutine curl_slist_free_all
451439
end interface
@@ -456,6 +444,7 @@ function curl_version_now() bind(c, name='curl_version_now')
456444
!! Interface to wrapper function `curl_version_now()` for C constant
457445
!! `CURLVERSION_NOW`.
458446
import :: c_int
447+
implicit none
459448
integer(kind=c_int) :: curl_version_now
460449
end function curl_version_now
461450
end interface
@@ -476,10 +465,31 @@ end function curl_version_now
476465
! size_t strlen(const char *str)
477466
function c_strlen(str) bind(c, name='strlen')
478467
import :: c_ptr, c_size_t
468+
implicit none
479469
type(c_ptr), intent(in), value :: str
480470
integer(kind=c_size_t) :: c_strlen
481471
end function c_strlen
482472
end interface
473+
474+
public :: c_f_str_ptr
475+
public :: curl_easy_init
476+
public :: curl_easy_perform
477+
public :: curl_easy_cleanup
478+
public :: curl_easy_setopt
479+
public :: curl_easy_setopt_c_ptr
480+
public :: curl_easy_setopt_c_funptr
481+
public :: curl_slist_append
482+
public :: curl_slist_free_all
483+
public :: curl_version_info
484+
public :: curl_version_now
485+
486+
private :: c_strlen
487+
private :: copy
488+
private :: curl_easy_setopt_char
489+
private :: curl_easy_setopt_fptr
490+
private :: curl_easy_setopt_int
491+
private :: curl_easy_setopt_long
492+
private :: curl_easy_setopt_ptr
483493
contains
484494
pure function copy(a)
485495
character, intent(in) :: a(:)
@@ -577,7 +587,7 @@ subroutine c_f_str_ptr(c_str, f_str, size)
577587
sz = c_strlen(c_str)
578588
end if
579589

580-
if (sz <= 0) return
590+
if (sz < 0) return
581591
call c_f_pointer(c_str, ptrs, [ sz ])
582592
allocate (character(len=sz) :: f_str)
583593
f_str = copy(ptrs)

0 commit comments

Comments
 (0)