Skip to content

Commit

Permalink
Merge pull request #66 from RyanGlScott/T65
Browse files Browse the repository at this point in the history
Adapt `u_memstream` code from `mesa`
  • Loading branch information
ianamason authored Mar 18, 2023
2 parents 11f645b + 59ee683 commit 126147f
Show file tree
Hide file tree
Showing 28 changed files with 339 additions and 45 deletions.
11 changes: 6 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
set(poly_SOURCES
set(poly_SOURCES
utils/debug_trace.c
utils/assignment.c
utils/statistics.c
utils/output.c
utils/sign_condition.c
utils/u_memstream.c
number/integer.c
number/rational.c
number/dyadic_rational.c
Expand Down Expand Up @@ -37,7 +38,7 @@ set(poly_SOURCES
poly.c
)

if (NOT HAVE_OPEN_MEMSTREAM)
if (NOT HAVE_OPEN_MEMSTREAM)
set(poly_SOURCES utils/open_memstream.c ${poly_SOURCES})
endif()

Expand Down Expand Up @@ -81,9 +82,9 @@ target_link_libraries(poly ${GMP_LIBRARY})

add_library(polyxx SHARED ${polyxx_SOURCES})
set_target_properties(polyxx PROPERTIES
VERSION ${LIBPOLY_VERSION}
VERSION ${LIBPOLY_VERSION}
SOVERSION ${LIBPOLY_VERSION_MAJOR}
)
)

target_link_libraries(polyxx poly ${GMP_LIBRARY})

Expand Down Expand Up @@ -121,7 +122,7 @@ endif()
#
# Linux, FreeBSD, and old versions of Darwin (and probably other systems) don't use fPIC by default.
# We just check for Linux and FreeBSD here.
#
#
if(LIBPOLY_BUILD_STATIC_PIC)
add_library(static_pic_poly STATIC ${poly_SOURCES})
set_target_properties(static_pic_poly PROPERTIES OUTPUT_NAME picpoly POSITION_INDEPENDENT_CODE true)
Expand Down
6 changes: 4 additions & 2 deletions src/interval/interval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1072,11 +1072,13 @@ int lp_interval_size_approx(const lp_interval_t* I) {
}

char* lp_interval_to_string(const lp_interval_t* I) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_interval_print(I, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
10 changes: 6 additions & 4 deletions src/number/algebraic_number.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,13 @@ int lp_algebraic_number_print(const lp_algebraic_number_t* a, FILE* out) {
}

char* lp_algebraic_number_to_string(const lp_algebraic_number_t* a) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_algebraic_number_print(a, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down Expand Up @@ -865,10 +867,10 @@ lp_upolynomial_t* lp_upolynomial_shift(const lp_upolynomial_t* poly, const lp_in
lp_upolynomial_unpack(poly, coeffs);

lp_upolynomial_t* out = lp_upolynomial_construct(lp_Z, 0, coeffs);

for (size_t i = 1; i <= lp_upolynomial_degree(poly); ++i) {
lp_upolynomial_t* cur = lp_upolynomial_mul_c(curmult, &coeffs[i]);

lp_upolynomial_t* tout = lp_upolynomial_add(out, cur);
lp_upolynomial_t* tcurmult = lp_upolynomial_mul(curmult, basemult);
lp_upolynomial_delete(cur);
Expand Down
6 changes: 4 additions & 2 deletions src/number/dyadic_rational.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,13 @@ int dyadic_rational_print(const lp_dyadic_rational_t* dq, FILE* out) {

static inline
char* dyadic_rational_to_string(const lp_dyadic_rational_t* q) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
dyadic_rational_print(q, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
6 changes: 4 additions & 2 deletions src/number/integer.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,13 @@ int lp_int_ring_print(const lp_int_ring_t* K, FILE* out) {
}

char* lp_int_ring_to_string(const lp_int_ring_t* K) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_int_ring_print(K, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
8 changes: 5 additions & 3 deletions src/number/integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include <assert.h>
#include <stdlib.h>

#include "utils/open_memstream.h"
#include "utils/u_memstream.h"
#include "utils/hash.h"

#define __var_unused(x) ((void)x)
Expand Down Expand Up @@ -141,11 +141,13 @@ int integer_print_matrix(const lp_integer_t* c, size_t m, size_t n, FILE* out) {

static inline
char* integer_to_string(const lp_integer_t* c) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
integer_print(c, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
8 changes: 5 additions & 3 deletions src/number/rational.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <rational.h>
#include <assert.h>

#include "utils/open_memstream.h"
#include "utils/u_memstream.h"

static inline
void rational_construct(lp_rational_t* q) {
Expand Down Expand Up @@ -94,11 +94,13 @@ int rational_print(const lp_rational_t* c, FILE* out) {

static inline
char* rational_to_string(const lp_rational_t* q) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
rational_print(q, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
6 changes: 4 additions & 2 deletions src/number/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,11 +599,13 @@ void lp_value_get_den(const lp_value_t* v, lp_integer_t* den) {
}

char* lp_value_to_string(const lp_value_t* v) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_value_print(v, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
6 changes: 4 additions & 2 deletions src/polynomial/feasibility_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,13 @@ int lp_feasibility_set_print(const lp_feasibility_set_t* set, FILE* out) {
}

char* lp_feasibility_set_to_string(const lp_feasibility_set_t* set) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_feasibility_set_print(set, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
6 changes: 4 additions & 2 deletions src/polynomial/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ int coefficient_print(const lp_polynomial_context_t* ctx, const coefficient_t* C
}

char* coefficient_to_string(const lp_polynomial_context_t* ctx, const coefficient_t* C) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
coefficient_print(ctx, C, f);
fclose(f);
u_memstream_close(&mem);
return str;
}
6 changes: 4 additions & 2 deletions src/upolynomial/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ int lp_upolynomial_print(const lp_upolynomial_t* p, FILE* out) {
}

char* lp_upolynomial_to_string(const lp_upolynomial_t* p) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_upolynomial_print(p, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
12 changes: 8 additions & 4 deletions src/utils/assignment.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ int lp_assignment_print(const lp_assignment_t* m, FILE* out) {
}

char* lp_assignment_to_string(const lp_assignment_t* m) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_assignment_print(m, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down Expand Up @@ -195,11 +197,13 @@ int lp_interval_assignment_print(const lp_interval_assignment_t* m, FILE* out) {
}

char* lp_interval_assignment_to_string(const lp_interval_assignment_t* m) {
struct u_memstream mem;
char* str = 0;
size_t size = 0;
FILE* f = open_memstream(&str, &size);
u_memstream_open(&mem, &str, &size);
FILE* f = u_memstream_get(&mem);
lp_interval_assignment_print(m, f);
fclose(f);
u_memstream_close(&mem);
return str;
}

Expand Down
100 changes: 100 additions & 0 deletions src/utils/u_memstream.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* A variation of open_memstream that works universally across multiple
* operating systems, including Windows. This implementation was adapted from
* the mesa source code at:
*
* https://gitlab.freedesktop.org/mesa/mesa/-/blob/14f9f98dcb4b6034c331120acf405e9a3c64edc6/src/util/memstream.c
*
* This mesa code is licensed under the MIT license. The copyright notice is
* reproduced below:
*/

/*
* Copyright 2020 Lag Free Games, LLC
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "utils/u_memstream.h"
#include "utils/open_memstream.h"

#include <stdlib.h>

#ifdef _WIN32
#include <windows.h>
#endif

bool
u_memstream_open(struct u_memstream *mem, char **bufp, size_t *sizep)
{
#if defined(_WIN32)
bool success = false;

char path[MAX_PATH];
DWORD dwResult = GetTempPath(MAX_PATH, path);
if ((dwResult > 0) && (dwResult < MAX_PATH)) {
char *temp = mem->temp;
UINT uResult = GetTempFileName(path, "MEMSTREAM", 0, temp);
if (uResult != 0) {
FILE *f = fopen(temp, "w+b");
success = f != NULL;
if (success)
{
mem->f = f;
mem->bufp = bufp;
mem->sizep = sizep;
}
}
}

return success;
#else
FILE *const f = open_memstream(bufp, sizep);
mem->f = f;
return f != NULL;
#endif
}

void
u_memstream_close(struct u_memstream *mem)
{
FILE *const f = mem->f;

#ifdef _WIN32
long size = ftell(f);
if (size > 0) {
/* reserve space for the null terminator */
char *buf = malloc(size + 1);
fseek(f, 0, SEEK_SET);
fread(buf, 1, size, f);
/* insert null terminator */
buf[size] = '\0';

*mem->bufp = buf;
*mem->sizep = size;
}

remove(mem->temp);
#endif

fclose(f);
}
Loading

0 comments on commit 126147f

Please sign in to comment.