From ddc0ff0140475b660ea842a41429514c16e3804f Mon Sep 17 00:00:00 2001 From: Nick Papior Date: Mon, 19 Feb 2024 11:23:53 +0100 Subject: [PATCH] ran pre-commit on the sources Signed-off-by: Nick Papior --- .arch.make | 3 +- Makefile.project | 2 +- README.md | 373 +++++++++++++++++++++------------------ arch-makes/clang.make | 2 +- arch-makes/gfortran.make | 1 - cmake/fdictFyppify.cmake | 1 - cmake/fdictOptions.cmake | 10 +- dist.sh | 2 +- fdict.pc.in | 1 - log.org | 25 ++- quick_test.sh | 4 +- smeka/Makefile.setup | 2 +- test/README.md | 4 +- test/crt_hash_basis.f90 | 4 +- test/tst_dict_hash.f90 | 6 +- 15 files changed, 234 insertions(+), 206 deletions(-) diff --git a/.arch.make b/.arch.make index 3a29f96..b19c12e 100644 --- a/.arch.make +++ b/.arch.make @@ -1,9 +1,8 @@ FC=gfortran -FFLAGS = -g +FFLAGS = -g .F90.o: $(FC) -c $(INC) $(FFLAGS) $(FPPFLAGS) $< .f90.o: $(FC) -c $(INC) $(FFLAGS) $< - diff --git a/Makefile.project b/Makefile.project index 78ddd89..4fdfa71 100644 --- a/Makefile.project +++ b/Makefile.project @@ -55,7 +55,7 @@ install-mod: $(F_MODS) .NOTPARALLEL: install-header smeka-install: install-header install-header: fdict.inc smeka-install-init-dir - $(INSTALL) -m $(_OCT_rwrr) -t $(DESTDIR)$(PREFIX)/$(INC_DIR) fdict.inc fdict.fypp + $(INSTALL) -m $(_OCT_rwrr) -t $(DESTDIR)$(PREFIX)/$(INC_DIR) fdict.inc fdict.fypp # Force the deletion of both libraries diff --git a/README.md b/README.md index af00d9a..edaae01 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# fdict # +# fdict [![Build Status](https://travis-ci.org/zerothi/fdict.svg?branch=master)](https://travis-ci.org/zerothi/fdict) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=NGNU2AA3JXX94&lc=DK&item_name=Papior%2dCodes&item_number=codes¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted) @@ -6,7 +6,7 @@ A variable and dictionary in pure fortran for retaining any data-type and a fast hash-table dictionary. -## Usage ## +## Usage This module consists of two separate modules which co-exist for maintenance and usage reasons. @@ -17,7 +17,7 @@ any variable type, and any dimension as well. Second, the dictionary module which contains a hash-table of variables that can contain _any_ data-type allowed by the variable module. -## Downloading and installation ## +## Downloading and installation Installing fdict requires a download of the library hosted at [github](https://github.com/) at [fdict@git]. @@ -31,15 +31,21 @@ CMake build. Extract and create an `setup.make` file for compilation, a minimal `setup.make` file can look like this - FC=gfortran - FFLAGS = -g - # if in a build directory, also add this: - PREFIX = +``` +FC=gfortran +FFLAGS = -g +``` + +# if in a build directory, also add this: + +PREFIX = Type `make` and a library called `libfdict.a` is created. Subsequently the installation may be performed by: - make PREFIX=/path/to/fdict install +``` +make PREFIX=/path/to/fdict install +``` which installs the required files (modules and libraries) to the folder. It will also install pkg-config files for auto-detection. @@ -48,13 +54,14 @@ It will also install pkg-config files for auto-detection. CMake procedure can be done via the normal procedure: - cmake -S. -Bbuild-fdict - cmake --build build-fdict +``` +cmake -S. -Bbuild-fdict +cmake --build build-fdict +``` fdict should also be able to be used in a sub-project. If problems occur, feel free to open up an issue. - ### Linking to fdict To use the dictionary you need to add include statements for the @@ -62,9 +69,11 @@ modules as well as linking to the program. To link fdict to your program the following can be used in a `Makefile` - FDICT_PATH = /path/to/fdict/parent - FDICT_LIBS = -L$(FDICT_PATH) -lfdict - FDICT_INC = -I$(FDICT_PATH) +``` +FDICT_PATH = /path/to/fdict/parent +FDICT_LIBS = -L$(FDICT_PATH) -lfdict +FDICT_INC = -I$(FDICT_PATH) +``` Alternatively, one can use pkg-config for obtaining the include flags and libraries. @@ -74,22 +83,24 @@ version one is using: 1. A simple header file (like C-preprocessor statements), this information is found in `fdict.inc` -2. A `fypp` compatible include file which contains library version and +1. A `fypp` compatible include file which contains library version and which data types are included in the built library, see the file `fdict.fypp` - The file `fdict.inc` may be included in projects which exposes the following definitions: - _FDICT_MAJOR_ 0 - _FDICT_MINOR_ 9 - _FDICT_PATCH_ 0 - _FDICT_VERSION_ 0.9.0 +``` +_FDICT_MAJOR_ 0 +_FDICT_MINOR_ 9 +_FDICT_PATCH_ 0 +_FDICT_VERSION_ 0.9.0 +``` This is mainly meant as a feature usable when the fdict interface and e.g. modules change names. Alternatively the `fdict.fypp` inclusion file exposes variables such as: + - the library version numbers (as above) - which data-types are enabled - the number of ranks for each kind @@ -98,8 +109,7 @@ The `fdict.fypp` file is handy when you are already relying on `fypp` whereas the regular `fdict.inc` header files are easy to use in standard fortran source compilation. - -#### Controlling interfaces #### +#### Controlling interfaces __Typically not needed__: allows for customization of different interfaces. @@ -113,47 +123,48 @@ interfaces. As the number of dimensions increases, so does the library size. If only a specific maximum range of ranks are required, it might be beneficial to reduce maximum ranks to the used range. - Currently the `fdict` library supports the types listed in the below table: -| Type | Precision format (GNU) | C-type | Default | -|-------------------|--------------------------|----------------------|---------| -| `type(variable_t)`| | --- | yes | -| `character(len=1)`| | `char` | yes | -| `integer` | `selected_int_kind(2)` | `byte` | no | -| `integer` | `selected_int_kind(4)` | `short` | no | -| `integer` | `selected_int_kind(9)` | `int` | yes | -| `integer` | `selected_int_kind(18)` | `long` | yes | -| `real` | `selected_real_kind(6)` | `float` | yes | -| `real` | `selected_real_kind(15)` | `double` | yes | -| `real` | `selected_real_kind(18)` | `ext. double` | no | -| `real` | `selected_real_kind(30)` | `quad` | no | -| `complex` | `selected_real_kind(6)` | `float complex` | yes | -| `complex` | `selected_real_kind(15)` | `double complex` | yes | -| `complex` | `selected_real_kind(18)` | `ext. double complex`| no | -| `complex` | `selected_real_kind(30)` | `quad complex` | no | -| `logical` | `selected_int_kind(2)` | `byte` | no | -| `logical` | `selected_int_kind(4)` | `short` | no | -| `logical` | `selected_int_kind(9)` | `int` | yes | -| `logical` | `selected_int_kind(18)` | `long` | no | -| `type(c_ptr)` | | `void *` | no | -| `type(c_funptr)` | | (procedure) `void *` | no | +| Type | Precision format (GNU) | C-type | Default | +| ------------------ | ------------------------ | --------------------- | ------- | +| `type(variable_t)` | | --- | yes | +| `character(len=1)` | | `char` | yes | +| `integer` | `selected_int_kind(2)` | `byte` | no | +| `integer` | `selected_int_kind(4)` | `short` | no | +| `integer` | `selected_int_kind(9)` | `int` | yes | +| `integer` | `selected_int_kind(18)` | `long` | yes | +| `real` | `selected_real_kind(6)` | `float` | yes | +| `real` | `selected_real_kind(15)` | `double` | yes | +| `real` | `selected_real_kind(18)` | `ext. double` | no | +| `real` | `selected_real_kind(30)` | `quad` | no | +| `complex` | `selected_real_kind(6)` | `float complex` | yes | +| `complex` | `selected_real_kind(15)` | `double complex` | yes | +| `complex` | `selected_real_kind(18)` | `ext. double complex` | no | +| `complex` | `selected_real_kind(30)` | `quad complex` | no | +| `logical` | `selected_int_kind(2)` | `byte` | no | +| `logical` | `selected_int_kind(4)` | `short` | no | +| `logical` | `selected_int_kind(9)` | `int` | yes | +| `logical` | `selected_int_kind(18)` | `long` | no | +| `type(c_ptr)` | | `void *` | no | +| `type(c_funptr)` | | (procedure) `void *` | no | In the `Default` column one can see which data-types are enabled by default. The most commonly used data-types are enabled. To enable the non-default data types you can do so with (Makefile scheme): - FYPPFLAGS += -DWITH_INT8=1 # for int kind(2) - FYPPFLAGS += -DWITH_INT16=1 # for int kind(4) - # Note that not all compilers support extended precisions - # If you experience compiler errors, this is likely the cause. - FYPPFLAGS += -DWITH_REAL80=1 # for real and complex kind(18) - FYPPFLAGS += -DWITH_REAL128=1 # for real and complex kind(30) - FYPPFLAGS += -DWITH_LOG8=1 # for logical kind(2) - FYPPFLAGS += -DWITH_LOG16=1 # for logical kind(4) - FYPPFLAGS += -DWITH_LOG64=1 # for logical kind(18) - FYPPFLAGS += -DWITH_ISO_C=1 # for enabling c_ptr and c_funptr +``` +FYPPFLAGS += -DWITH_INT8=1 # for int kind(2) +FYPPFLAGS += -DWITH_INT16=1 # for int kind(4) +# Note that not all compilers support extended precisions +# If you experience compiler errors, this is likely the cause. +FYPPFLAGS += -DWITH_REAL80=1 # for real and complex kind(18) +FYPPFLAGS += -DWITH_REAL128=1 # for real and complex kind(30) +FYPPFLAGS += -DWITH_LOG8=1 # for logical kind(2) +FYPPFLAGS += -DWITH_LOG16=1 # for logical kind(4) +FYPPFLAGS += -DWITH_LOG64=1 # for logical kind(18) +FYPPFLAGS += -DWITH_ISO_C=1 # for enabling c_ptr and c_funptr +``` For `cmake` the same arguments can be made at the command-line. @@ -162,67 +173,76 @@ however, if one wishes to use the `iso_fortran_env` module simply add `FYPPFLAGS To control the maximum ranks in the interfaces one can add these: - # type(c_ptr), type(c_funptr) and character(len=1) - # are data types that are not affected by the MAXRANK variable - - # globally define the maximum ranks of all but the above listed - FYPPFLAGS += -DMAXRANK=n +``` +# type(c_ptr), type(c_funptr) and character(len=1) +# are data types that are not affected by the MAXRANK variable - # integer(*) types maximum rank - FYPPFLAGS += -DMAXRANK_INT=n +# globally define the maximum ranks of all but the above listed +FYPPFLAGS += -DMAXRANK=n - # real(*) types maximum rank - FYPPFLAGS += -DMAXRANK_REAL=n +# integer(*) types maximum rank +FYPPFLAGS += -DMAXRANK_INT=n - # complex(*) types maximum rank - FYPPFLAGS += -DMAXRANK_CMPLX=n +# real(*) types maximum rank +FYPPFLAGS += -DMAXRANK_REAL=n - # logical(*) types maximum rank - FYPPFLAGS += -DMAXRANK_LOG=n +# complex(*) types maximum rank +FYPPFLAGS += -DMAXRANK_CMPLX=n - # type(c_ptr), type(c_funptr) types maximum rank - FYPPFLAGS += -DMAXRANK_ISO_C=n +# logical(*) types maximum rank +FYPPFLAGS += -DMAXRANK_LOG=n +# type(c_ptr), type(c_funptr) types maximum rank +FYPPFLAGS += -DMAXRANK_ISO_C=n +``` -### variable ### +### variable Using this module one gains access to a generic type variable which can contain _any_ data format. It is used like this: - use variable - integer :: a(3 - type(variable_t) :: v - a = 2 - call assign(v,a) - a = 3 - call assign(a,v) +``` +use variable +integer :: a(3 +type(variable_t) :: v +a = 2 +call assign(v,a) +a = 3 +call assign(a,v) +``` Also the variable contains an abbreviation for assigning pointers to not copy data, but retain data locality: - integer, target :: a(3) - type(variable_t) :: v - a = 2 - call associate(v,a) - a = 3 - ! Now v contains a = 3 +``` +integer, target :: a(3) +type(variable_t) :: v +a = 2 +call associate(v,a) +a = 3 +! Now v contains a = 3 +``` To delete a variable do: - use variable - type(variable_t) :: v - call delete(v) +``` +use variable +type(variable_t) :: v +call delete(v) +``` However, when the variable is using pointers, instead the user can do - use variable - type(variable_t) :: v - ! preferred - call nullify(v) - ! or - call delete(v,dealloc=.false.) +``` +use variable +type(variable_t) :: v +! preferred +call nullify(v) +! or +call delete(v,dealloc=.false.) +``` which merely destroys the variable object and thus retains the data where it is. As with any other pointer arithmetic it is up to the programmer @@ -231,33 +251,34 @@ to ensure there is no memory leaks. In some cases one does not know which data-type is being stored in a variable. Here it may be beneficial to lookup the type of data: - use variable - integer, target :: a(3) - type(variable_t) :: v - a(:) = 2 - call associate(v,a) - if ( which(v) == which(a) ) then ! signal integer of 1D (i0 for scalar) - call assign(a, v) - end if - - ! Another possibility is to *try* to get the value - logical :: success - integer, target :: i1(3) - real, target :: r1(3) - - call assign(r1, v, success=success) - if ( .not. success ) then - call assign(i1, v, success=success) - end if - ... etc ... +``` +use variable +integer, target :: a(3) +type(variable_t) :: v +a(:) = 2 +call associate(v,a) +if ( which(v) == which(a) ) then ! signal integer of 1D (i0 for scalar) + call assign(a, v) +end if + +! Another possibility is to *try* to get the value +logical :: success +integer, target :: i1(3) +real, target :: r1(3) + +call assign(r1, v, success=success) +if ( .not. success ) then + call assign(i1, v, success=success) +end if +... etc ... +``` However, it may be better to explicitly check the type using `which`. For consistency and API changes, it is encouraged to use `which()` to ensure that the data-types are as expected. I.e. `which([real(real64) ::])` is the preferred way of forcing a data-type contained in a variable. - -### dictionary ### +### dictionary Using `type(variable_t)` it becomes easy to create dictionaries in fortran. @@ -271,30 +292,38 @@ Concatenating dictionaries is also very fast. Creating a dictionary is almost as easy as the Python equivalent: - use dictionary - type(dictionary_t) :: dict - dict = ('KEY'.kv.1) +``` +use dictionary +type(dictionary_t) :: dict +dict = ('KEY'.kv.1) +``` To extend a dictionary one uses the concatenating format: - dict = dict // ('Hello'.kv.'world') // ('No'.kv.'world') +``` +dict = dict // ('Hello'.kv.'world') // ('No'.kv.'world') +``` Again as is used by the `type(variable_t)` one can with benefit use `.kvp.` to create the dictionary value by pointers instead of copying the content. Hence doing: - real :: r(4) - dict = dict // ('reals'.kvp.r) - r = 4 +``` +real :: r(4) +dict = dict // ('reals'.kvp.r) +r = 4 +``` will change the value in the dictionary. Note that one can easily create memory leaks with dictionaries: - use dictionary - type(dictionary_t) :: dict - dict = ('KEY'.kv.1) - dict = dict // ('KEY'.kv.2) - dict = ('KEY'.kv.3) +``` +use dictionary +type(dictionary_t) :: dict +dict = ('KEY'.kv.1) +dict = dict // ('KEY'.kv.2) +dict = ('KEY'.kv.3) +``` The 1st assignement is valid since the dictionary is empty. The 2nd assignment concatenates and does not produce any memory leaks. @@ -303,51 +332,53 @@ The 3rd assignment produces a memory leak since the pointer to the original dictionary gets lost. Be sure to call `call delete(dict)` prior to single assignments. - There are various ways to access the data in a dictionary. 1. Accessing specific keys may be exercised using - use dictionary - type(dictionary_t) :: dict - type(variable_t) :: var - integer :: i - real :: r - logical :: success - dict = ('KEY'.kv.1) - call assign(r, dict, 'KEY', success=success) - if ( .not. success ) call assign(i, dict, 'KEY', success=success) - call assign(var, dict, 'KEY') + ``` + use dictionary + type(dictionary_t) :: dict + type(variable_t) :: var + integer :: i + real :: r + logical :: success + dict = ('KEY'.kv.1) + call assign(r, dict, 'KEY', success=success) + if ( .not. success ) call assign(i, dict, 'KEY', success=success) + call assign(var, dict, 'KEY') + ``` Since values in dictionaries are stored using `variable_t` we have to follow the limitations of that implementation. Therefore it may be better to always use a temporary `variable_t` to retrieve the values stored. This will remove a redundant lookup in the dictionary. -2. Users may find the `.key.` and `.value.` operators which only acts on the first +1. Users may find the `.key.` and `.value.` operators which only acts on the first element of the dictionary (which may be a surprise). This is only useful for looping dictionaries. - use dictionary - type(dictionary_t) :: dict, dict_first - type(variable_t) :: var - character(DICTIONARY_KEY_LENGTH) :: key - integer :: i - real :: r - logical :: success - dict = ('KEY'.kv.1) - dict = dict // ('KEY1'.kv.3) - - ! start looping - dict_first = .first. dict - do while ( .not. (.empty. dict_first) ) - ! now .key. and .value. could be used: - key = .key. dict_first - call assign(var, dict_first) - ! Get next dictionary entry - dict_first = .next. dict_first - end while - + ``` + use dictionary + type(dictionary_t) :: dict, dict_first + type(variable_t) :: var + character(DICTIONARY_KEY_LENGTH) :: key + integer :: i + real :: r + logical :: success + dict = ('KEY'.kv.1) + dict = dict // ('KEY1'.kv.3) + + ! start looping + dict_first = .first. dict + do while ( .not. (.empty. dict_first) ) + ! now .key. and .value. could be used: + key = .key. dict_first + call assign(var, dict_first) + ! Get next dictionary entry + dict_first = .next. dict_first + end while + ``` Note that the dictionary can also contain _any_ data type. @@ -356,11 +387,13 @@ extend the code by supplying a few custom routines. Intrinsically the dictionary can contain dictionaries by this: - use dictionary - type(dictionary_t) :: d1, d2 - d1 = ('hello'.kv.'world') - d2 = ('hello'.kv.'world') - d1 = d1 // ('dict'.kvp.d2) +``` +use dictionary +type(dictionary_t) :: d1, d2 +d1 = ('hello'.kv.'world') +d2 = ('hello'.kv.'world') +d1 = d1 // ('dict'.kvp.d2) +``` But it will be up to the user to _know_ the key for data types other than integers, reals, complex numbers, characters and `c_*` extension types. @@ -368,8 +401,7 @@ integers, reals, complex numbers, characters and `c_*` extension types. Note that the dictionary contained is passed by reference, and thus if you delete `d2`, you will have a dangling pointer in `d1`. - -## Contributions, issues and bugs ## +## Contributions, issues and bugs I would advice any users to contribute as much feedback and/or PRs to further maintain and expand this library. @@ -380,12 +412,11 @@ If you find any bugs please form a [bug report/issue][issue]. If you have a fix please consider adding a [pull request][pr]. - -## License ## +## License The fdict license is [MPL-2.0][mpl-2], see the LICENSE file. -## Thanks ## +## Thanks A big thanks goes to Alberto Garcia for contributing ideas and giving me bug reports. Without him the interface would have been much more @@ -394,8 +425,10 @@ complex! -[fdict@git]: https://github.com/zerothi/fdict + + +[fdict@git]: https://github.com/zerothi/fdict [issue]: https://github.com/zerothi/fdict/issues -[pr]: https://github.com/zerothi/fdict/pulls [mpl-2]: https://opensource.org/licenses/MPL-2.0 +[pr]: https://github.com/zerothi/fdict/pulls diff --git a/arch-makes/clang.make b/arch-makes/clang.make index ddd1037..52714dc 100644 --- a/arch-makes/clang.make +++ b/arch-makes/clang.make @@ -1,7 +1,7 @@ FC=clang FC_SERIAL=clang -FFLAGS=-O3 -m64 -fPIC -funroll-loops -freroll-loops +FFLAGS=-O3 -m64 -fPIC -funroll-loops -freroll-loops #FFLAGS += -Wunused diff --git a/arch-makes/gfortran.make b/arch-makes/gfortran.make index 6a1330f..075ad6c 100644 --- a/arch-makes/gfortran.make +++ b/arch-makes/gfortran.make @@ -15,4 +15,3 @@ FFLAGS=-O2 -m64 -fPIC # This is for debugging purposes #FFLAGS = -g -O0 -Warray-bounds -Wunused - diff --git a/cmake/fdictFyppify.cmake b/cmake/fdictFyppify.cmake index 69c28aa..5a680e7 100644 --- a/cmake/fdictFyppify.cmake +++ b/cmake/fdictFyppify.cmake @@ -85,4 +85,3 @@ function(fdict_fyppify) endif() endfunction() - diff --git a/cmake/fdictOptions.cmake b/cmake/fdictOptions.cmake index c7acf75..9be944a 100644 --- a/cmake/fdictOptions.cmake +++ b/cmake/fdictOptions.cmake @@ -25,10 +25,10 @@ endfunction() function(fortran_test_type type result) # type = INT,real,REAL for data-type checking # define the source code that should be compiled - + # Create unique test-name string(REGEX REPLACE "[\\(\\)]" "_" testname "f90_type_${type}") - + # get the data type fortran_conv_type(${type} actual_type) if("${type}" STREQUAL "ISO_C") @@ -65,11 +65,11 @@ function(fortran_test_rank_size type rank result) # get data-type fortran_conv_type(${type} actual_type) - + if("${type}" STREQUAL "ISO_C") set(source " use, intrinsic :: iso_c_binding - ${actual_type}, allocatable :: p${_dims} + ${actual_type}, allocatable :: p${_dims} end") else() set(source " @@ -131,7 +131,7 @@ if(${WITH_ISO_ENV}) end") check_fortran_source_runs("${source}" result) list(POP_BACK CMAKE_MESSAGE_INDENT " ") - + if(NOT "${result}") message(CHECK_FAIL "could not compile source: ${source}") message(FATAL_ERROR "Requested use of iso_fortran_env, but the compiler does not support it! Remove WITH_ISO_ENV=true from command line or change compiler!") diff --git a/dist.sh b/dist.sh index e740f9e..8d7e380 100755 --- a/dist.sh +++ b/dist.sh @@ -19,4 +19,4 @@ git archive --prefix $_name-$describe/ \ -o $file HEAD # printout the created filename -echo $file \ No newline at end of file +echo $file diff --git a/fdict.pc.in b/fdict.pc.in index 29e6db0..8386fa6 100644 --- a/fdict.pc.in +++ b/fdict.pc.in @@ -12,4 +12,3 @@ Version: @PROJECT_VERSION@ URL: https://github.com/zerothi/fdict Cflags: -I${includedir} Libs: -L${libdir} -lfdict - diff --git a/log.org b/log.org index 271c9e0..c44387c 100644 --- a/log.org +++ b/log.org @@ -5,7 +5,7 @@ Every section in this part lists the change of the versions The dictionary will make use of the var format for retaining any type of -data. This will allow for greater structure +data. This will allow for greater structure ** Changed build system <2016-05-14 Sat> Now the build system has been changed. I still need to document the build system, but essentially one @@ -92,7 +92,7 @@ The problem with user-types in dictionaries is that deleting a variable with a custom type is not well defined. Hence, a deletion of a dictionary will NOT delete custom types for obvious reasons. -It will not even delete dictionaries as it does not +It will not even delete dictionaries as it does not know the value of a custom type to be a dictionary. A small test example has been added. @@ -106,18 +106,18 @@ However, the fact that any information regarding the contained data type is hidden for the variable type means that there are certain limitations. -1. The user cannot assign user-types. It makes no sense as the +1. The user cannot assign user-types. It makes no sense as the data cannot be copied, we can only copy the pointer. 2. Retrieval of data of a variable has to be done by the programmer - (add variable retrieval in the code that defines the data type, + (add variable retrieval in the code that defines the data type, and thats it) -3. +3. ** Added dealloc specifier for delete <2014-10-19 Sun> When deleting a dictionary, or key in dictionary one -can now only delete the reference. +can now only delete the reference. This is handy if the .kvp. has been used. -Also improved specific key deletion by adding a +Also improved specific key deletion by adding a hash-check. ** Added .NIN. and .VALP. routines <2014-10-19 Sun> @@ -137,7 +137,7 @@ is saved via an encoding realised as: type(ptr) :: p character(len=1), allocatable :: enc(:) real :: a(2) - + allocate(enc(size(transfer(a,p))) enc = transfer(a,p) @@ -164,7 +164,7 @@ I had forgotten to enable direct assignment "call assign(val,dic)" this has been fixed. ** Added a which(this,key) for the dictionary <2014-05-30 Fri> -It enables a direct look on the data type to assert without +It enables a direct look on the data type to assert without having to fetch to a type(var) ** Renamed add => extend <2014-05-30 Fri> @@ -199,12 +199,12 @@ dictionary code. For calling routines: call routine('hello'.kv.'h') we have a memory leak. This is obvious due to the pointer -nature of the data associated. +nature of the data associated. A test has been added to demonstrate this effect: tst_dict_mem3 ** Renamed .HAS. to .IN. <2014-05-25 Sun> -A more appropriate name has been chosen for checking +A more appropriate name has been chosen for checking existence of keys in dictionaries. Much like python we rely on the .IN. to check for the existence. @@ -218,8 +218,7 @@ This is the expected behaviour in any language. The dictionary values are now the type(var) which eases the interfacing between different segments of the code. We allow to fully utilise the "assign" and "associate" -function calls in the assignment of the dictionary by following the +function calls in the assignment of the dictionary by following the operators: .KV. (assign) .KPV. (associate) - diff --git a/quick_test.sh b/quick_test.sh index eeff566..75498d3 100755 --- a/quick_test.sh +++ b/quick_test.sh @@ -5,7 +5,7 @@ _old_arch= if [ -L arch.make ]; then - # We assume the arch.make is + # We assume the arch.make is # a link to .arch.make # Simply delete it, we will re-instantiate it rm arch.make @@ -29,4 +29,4 @@ if [ -z "$_old_arch" ]; then else rm arch.make mv $_old_arch arch.make -fi \ No newline at end of file +fi diff --git a/smeka/Makefile.setup b/smeka/Makefile.setup index 60b4455..55a8e49 100644 --- a/smeka/Makefile.setup +++ b/smeka/Makefile.setup @@ -79,7 +79,7 @@ endif # Add print-out to target .PHONY: smeka-settings-custom -smeka-settings-custom: +smeka-settings-custom: @$(ECHO) "" @$(ECHO) "Using custom settings:" @$(ECHO) " $(SETUP)" diff --git a/test/README.md b/test/README.md index 2eaa9ff..521ff3c 100644 --- a/test/README.md +++ b/test/README.md @@ -1,5 +1,5 @@ -Tests ------ +## Tests + Tests for `fdict`. Currently many of the tests are leaking memory, some on purpose on others because it was easier to implement the test. diff --git a/test/crt_hash_basis.f90 b/test/crt_hash_basis.f90 index 9cac959..9114c71 100644 --- a/test/crt_hash_basis.f90 +++ b/test/crt_hash_basis.f90 @@ -6,7 +6,7 @@ program fnv_hash integer :: offset character(len=36) :: b = 'fdict \\./o\\/ ' integer :: i - + print '(2a)','Basis offset: ',trim(b) offset = 0 hash_mod = 2**16 @@ -16,5 +16,5 @@ program fnv_hash end do print *,offset - + end program fnv_hash diff --git a/test/tst_dict_hash.f90 b/test/tst_dict_hash.f90 index 1a83b42..9bacd1d 100644 --- a/test/tst_dict_hash.f90 +++ b/test/tst_dict_hash.f90 @@ -21,9 +21,9 @@ program tests ! add to dictionary d = d // (trim(line).kvp.i0) - + end do - + ! close the file handle close(iu) @@ -36,5 +36,5 @@ program tests call delete(d,dealloc=.false.) print *,'SUCCESS' - + end program tests