summaryrefslogtreecommitdiff
path: root/prism/source.h
diff options
context:
space:
mode:
Diffstat (limited to 'prism/source.h')
-rw-r--r--prism/source.h148
1 files changed, 148 insertions, 0 deletions
diff --git a/prism/source.h b/prism/source.h
new file mode 100644
index 0000000000..c79987d3fb
--- /dev/null
+++ b/prism/source.h
@@ -0,0 +1,148 @@
+/**
+ * @file source.h
+ *
+ * An opaque type representing the source code being parsed, regardless of
+ * origin (constant memory, file, memory-mapped file, or stream).
+ */
+#ifndef PRISM_SOURCE_H
+#define PRISM_SOURCE_H
+
+#include "prism/compiler/exported.h"
+#include "prism/compiler/filesystem.h"
+#include "prism/compiler/nodiscard.h"
+#include "prism/compiler/nonnull.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * An opaque type representing source code being parsed.
+ */
+typedef struct pm_source_t pm_source_t;
+
+/**
+ * This function is used to retrieve a line of input from a stream. It closely
+ * mirrors that of fgets so that fgets can be used as the default
+ * implementation.
+ */
+typedef char * (pm_source_stream_fgets_t)(char *string, int size, void *stream);
+
+/**
+ * This function is used to check whether a stream is at EOF. It closely mirrors
+ * that of feof so that feof can be used as the default implementation.
+ */
+typedef int (pm_source_stream_feof_t)(void *stream);
+
+/**
+ * Represents the result of initializing a source from a file.
+ */
+typedef enum {
+ /** Indicates that the source was successfully initialized. */
+ PM_SOURCE_INIT_SUCCESS = 0,
+
+ /**
+ * Indicates a generic error from a source init function, where the type
+ * of error should be read from `errno` or `GetLastError()`.
+ */
+ PM_SOURCE_INIT_ERROR_GENERIC = 1,
+
+ /**
+ * Indicates that the file that was attempted to be opened was a directory.
+ */
+ PM_SOURCE_INIT_ERROR_DIRECTORY = 2,
+
+ /**
+ * Indicates that the file is not a regular file (e.g. a pipe or character
+ * device) and the caller should handle reading it.
+ */
+ PM_SOURCE_INIT_ERROR_NON_REGULAR = 3
+} pm_source_init_result_t;
+
+/**
+ * Create a new source that wraps existing constant memory. The memory is not
+ * owned and will not be freed.
+ *
+ * @param data The pointer to the source data.
+ * @param length The length of the source data in bytes.
+ * @returns A new source. Aborts on allocation failure.
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_constant_new(const uint8_t *data, size_t length);
+
+/**
+ * Create a new source that wraps existing shared memory. The memory is not
+ * owned and will not be freed. Semantically a "slice" of another source.
+ *
+ * @param data The pointer to the source data.
+ * @param length The length of the source data in bytes.
+ * @returns A new source. Aborts on allocation failure.
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_shared_new(const uint8_t *data, size_t length);
+
+/**
+ * Create a new source that owns its memory. The memory will be freed with
+ * xfree when the source is freed.
+ *
+ * @param data The pointer to the heap-allocated source data.
+ * @param length The length of the source data in bytes.
+ * @returns A new source. Aborts on allocation failure.
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_owned_new(uint8_t *data, size_t length);
+
+/**
+ * Create a new source by reading a file into a heap-allocated buffer.
+ *
+ * @param filepath The path to the file to read.
+ * @param result Out parameter for the result of the initialization.
+ * @returns A new source, or NULL on error (with result written to out param).
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_file_new(const char *filepath, pm_source_init_result_t *result) PRISM_NONNULL(1, 2);
+
+/**
+ * Create a new source by memory-mapping a file. Falls back to file reading on
+ * platforms without mmap support.
+ *
+ * If the file is a non-regular file (e.g. a pipe or character device),
+ * PM_SOURCE_INIT_ERROR_NON_REGULAR is returned, allowing the caller to handle
+ * it appropriately (e.g. by reading it through their own I/O layer).
+ *
+ * @param filepath The path to the file to read.
+ * @param open_flags Additional flags to pass to open(2) (e.g. O_NONBLOCK).
+ * @param result Out parameter for the result of the initialization.
+ * @returns A new source, or NULL on error (with result written to out param).
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_mapped_new(const char *filepath, int open_flags, pm_source_init_result_t *result) PRISM_NONNULL(1, 3);
+
+/**
+ * Create a new source by reading from a stream using the provided callbacks.
+ *
+ * @param stream The stream to read from.
+ * @param fgets The function to use to read from the stream.
+ * @param feof The function to use to check if the stream is at EOF.
+ * @returns A new source. Aborts on allocation failure.
+ */
+PRISM_EXPORTED_FUNCTION PRISM_NODISCARD pm_source_t * pm_source_stream_new(void *stream, pm_source_stream_fgets_t *fgets, pm_source_stream_feof_t *feof);
+
+/**
+ * Free the given source and any memory it owns.
+ *
+ * @param source The source to free.
+ */
+PRISM_EXPORTED_FUNCTION void pm_source_free(pm_source_t *source) PRISM_NONNULL(1);
+
+/**
+ * Returns the length of the source data in bytes.
+ *
+ * @param source The source to get the length of.
+ * @returns The length of the source data.
+ */
+PRISM_EXPORTED_FUNCTION size_t pm_source_length(const pm_source_t *source) PRISM_NONNULL(1);
+
+/**
+ * Returns a pointer to the source data.
+ *
+ * @param source The source to get the data of.
+ * @returns A pointer to the source data.
+ */
+PRISM_EXPORTED_FUNCTION const uint8_t * pm_source_source(const pm_source_t *source) PRISM_NONNULL(1);
+
+#endif