--- /dev/null
+/*
+ Copyright (C) 2012 Modelon AB
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the BSD style license.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ FMILIB_License.txt file for more details.
+
+ You should have received a copy of the FMILIB_License.txt file
+ along with this program. If not, contact Modelon AB <http://www.modelon.com>.
+*/
+
+#ifndef JM_STRING_SET_H
+#define JM_STRING_SET_H
+
+#include <string.h>
+#include <stdio.h>
+
+#include "jm_types.h"
+#include "jm_vector.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+/** \file jm_string_set.h Definition of ::jm_string_set and supporting functions
+ *
+ * \addtogroup jm_utils
+ * @{
+ * \addtogroup jm_string_set_group
+ * @}
+ */
+
+ /** \addtogroup jm_string_set_group A set of strings
+ @{
+ */
+
+/**
+ \brief Set of string is based on a vector
+
+*/
+typedef struct jm_vector_jm_string jm_string_set; /* equivalent to "typedef jm_vector(jm_string) jm_string_set" which Doxygen does not understand */
+
+/**
+\brief Find a string in a set.
+
+\param s A string set.
+\param str Search string.
+\return If found returns a pointer to the string saved in the set. If not found returns NULL.
+*/
+static jm_string jm_string_set_find(jm_string_set* s, jm_string str) {
+ jm_string* found = jm_vector_bsearch(jm_string)(s,&str,jm_compare_string);
+ if(found) return *found;
+ return 0;
+}
+
+/**
+\brief Find index of a string in a set.
+
+\param s A string set.
+\param str Search string.
+\return If found returns the index to the string saved in the set. If not found returns the insertion index of the string.
+*/
+static size_t jm_string_set_find_index(jm_string_set* s, jm_string str) {
+ size_t len = jm_vector_get_size(jm_string)(s);
+ size_t first = 0;
+ size_t mid = 0;
+ size_t last = len - 1;
+ if(len == 0) {
+ return 0;
+ }
+ while (first <= last) {
+ mid = (last + first)/2;
+ if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) == 0) {
+ return mid;
+ } else if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) > 0) {
+ if (mid == 0) return first;
+ last = mid - 1;
+ } else if (strcmp(jm_vector_get_item(jm_string)(s,mid), str) < 0) {
+ first = mid + 1;
+ }
+ }
+ return first;
+}
+
+/**
+* \brief Put an element in the set if it is not there yet.
+*
+* @param s A string set.
+* \param str String to put.
+* @return A pointer to the inserted (or found) element or zero pointer if failed.
+*/
+static jm_string jm_string_set_put(jm_string_set* s, jm_string str) {
+ jm_string* pnewstr;
+ char* newstr = 0;
+ size_t len = strlen(str) + 1;
+ size_t idx = jm_string_set_find_index(s, str);
+
+ if (idx != jm_vector_get_size(jm_string)(s)) {
+ if (strcmp(jm_vector_get_item(jm_string)(s, idx), str) != 0) {
+ pnewstr = jm_vector_insert(jm_string)(s, idx, str);
+ } else {
+ return jm_vector_get_item(jm_string)(s, idx);
+ }
+ } else {
+ pnewstr = jm_vector_push_back(jm_string)(s, str);
+ }
+ if(pnewstr) *pnewstr = newstr = s->callbacks->malloc(len);
+ if(!pnewstr || !newstr) return 0;
+ memcpy(newstr, str, len);
+ return *pnewstr;
+}
+
+/** @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JM_STRING_SET_H */