summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorJjgod Jiang <gzjjgod@gmail.com>2007-11-20 08:50:29 +0000
committerJjgod Jiang <gzjjgod@gmail.com>2007-11-20 08:50:29 +0000
commit5e225d257c6d1f38a26a84ef299666eeaa676a9b (patch)
tree55347b7fe3d03f75fb19a46de6b373e043321071 /Master
parentd9e6221bd1c00ef10da9a274657e35b922ba3e5d (diff)
Initial commit of libtlp (texlive package library in C).
git-svn-id: svn://tug.org/texlive/trunk@5528 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/tlpkg/lib/C/tlp-src.c314
-rw-r--r--Master/tlpkg/lib/C/tlp-src.h75
-rw-r--r--Master/tlpkg/lib/C/tlp-utils.c98
-rw-r--r--Master/tlpkg/lib/C/tlp-utils.h61
4 files changed, 548 insertions, 0 deletions
diff --git a/Master/tlpkg/lib/C/tlp-src.c b/Master/tlpkg/lib/C/tlp-src.c
new file mode 100644
index 00000000000..13d33df823f
--- /dev/null
+++ b/Master/tlpkg/lib/C/tlp-src.c
@@ -0,0 +1,314 @@
+/* tlp-src.c - module for using tlpsrc files
+ *
+ * Copyright 2007 Jjgod Jiang
+ * Derived from the Perl implementation by Norbert Preining
+ *
+ * This file is licensed under the GNU General Public License version 2
+ * or any later version. */
+
+#include <tlp-src.h>
+#include <stdio.h>
+
+/* internal function prototypes {{{ */
+
+tlp_result tlp_src_process_line(tlp_src *src, tlp_str line,
+ int *started, int *finished,
+ const char *file);
+
+tlp_result tlp_str_get_word(tlp_str str, tlp_str word, int max);
+
+tlp_result tlp_src_get_name(tlp_str line,
+ tlp_src *src,
+ int *started,
+ const char *file);
+
+/* }}} */
+
+/* internal data structures {{{ */
+
+struct tlp_src_field {
+ tlp_str key;
+ tlp_result (*func)(tlp_str line,
+ tlp_src *src,
+ int *started,
+ const char *file);
+};
+
+/* for lines start with "name", we use function tlp_src_get_name() to
+ * process it, and feed it with the current tlp_src instance. */
+
+struct tlp_src_field tlp_src_fields[] = {
+ { TLP_STR("name"), tlp_src_get_name }, /*
+ { TLP_STR("category"), tlp_src_get_category },
+ { TLP_STR("shortdesc"), tlp_src_get_shortdesc },
+ { TLP_STR("longdesc"), tlp_src_get_longdesc },
+ { TLP_STR("catalogue"), tlp_src_get_catalogue },
+
+ { TLP_STR("runpatterns"), tlp_src_get_runpatterns },
+ { TLP_STR("srcpatterns"), tlp_src_get_srcpatterns },
+ { TLP_STR("docpatterns"), tlp_src_get_docpatterns },
+ { TLP_STR("binpatterns"), tlp_src_get_binpatterns },
+
+ { TLP_STR("execute"), tlp_src_get_execute },
+ { TLP_STR("depend"), tlp_src_get_depend }, */
+};
+
+#define TLP_SRC_TOTAL_FIELDS (sizeof(tlp_src_fields) / sizeof(tlp_src_fields[0]))
+
+/* }}} */
+
+/* tlp_src related {{{ */
+
+tlp_src *tlp_src_new(tlp_str name,
+ tlp_str category,
+ tlp_str shortdesc,
+ tlp_str longdesc,
+ tlp_str catalogue,
+ tlp_pattern *runpatterns,
+ tlp_pattern *srcpatterns,
+ tlp_pattern *docpatterns,
+ tlp_pattern *binpatterns,
+ tlp_execute *executes,
+ tlp_depend *depends)
+{
+ tlp_src *src = tlp_new(tlp_src);
+ if (! src)
+ return NULL;
+
+ src->name = tlp_str_copy(name);
+ src->category = tlp_str_copy(category);
+ src->shortdesc = tlp_str_copy(shortdesc);
+ src->longdesc = tlp_str_copy(longdesc);
+ src->catalogue = tlp_str_copy(catalogue);
+
+ src->runpatterns = runpatterns;
+ src->srcpatterns = srcpatterns;
+ src->docpatterns = docpatterns;
+ src->binpatterns = binpatterns;
+
+ src->executes = executes;
+ src->depends = depends;
+
+ return src;
+}
+
+void tlp_src_free(tlp_src *src)
+{
+ if (! src)
+ return;
+
+ tlp_str_free(src->name);
+ tlp_str_free(src->category);
+ tlp_str_free(src->shortdesc);
+ tlp_str_free(src->longdesc);
+ tlp_str_free(src->catalogue);
+
+ tlp_patterns_free(src->runpatterns);
+ tlp_patterns_free(src->srcpatterns);
+ tlp_patterns_free(src->docpatterns);
+ tlp_patterns_free(src->binpatterns);
+
+ tlp_executes_free(src->executes);
+ tlp_depends_free(src->depends);
+
+ free(src);
+ src = NULL;
+}
+
+tlp_src *tlp_src_from_file(char *file)
+{
+ FILE *fp;
+ tlp_src *src;
+ tlp_char line[TLP_SRC_LINE_MAX];
+ int started, finished;
+
+ fp = fopen(file, "r");
+ if (! fp)
+ return NULL;
+
+ src = tlp_new(tlp_src);
+
+ /* TODO: if the argument is not readable as is, try looking
+ * for it in the hierarchy where we are.*/
+ if (! src)
+ return NULL;
+
+ started = finished = 0;
+
+ while (tlp_fgets(line, TLP_SRC_LINE_MAX, fp))
+ {
+ if (tlp_src_process_line(src, line,
+ &started,
+ &finished,
+ file) != TLP_OK)
+ goto failed;
+ }
+
+ fclose(fp);
+ return src;
+
+failed:
+ tlp_src_free(src);
+ fclose(fp);
+ return NULL;
+}
+
+tlp_result tlp_src_process_line(tlp_src *src, tlp_str line,
+ int *started, int *finished,
+ const char *file)
+{
+ int i;
+
+ /* skip all leading spaces */
+ for (i = 0; tlp_char_is_space(line[i]); i++)
+ ;
+
+ /* skip comment lines */
+ if (line[i] == TLP_CHAR_COMMENT)
+ return TLP_OK;
+
+ if (tlp_char_is_eol(line[i]))
+ {
+ if (! *started || *finished)
+ return TLP_OK;
+
+ tlp_error_msg("%s: empty line not allowed in tlpsrc\n", file);
+ return TLP_FAILED;
+ }
+
+ /* something like " name ..." is not allowed */
+ if (line[0] == ' ')
+ {
+ tlp_error_msg("%s: continuation line not allowed in tlpsrc: ", file);
+ tlp_error_str(line);
+
+ return TLP_FAILED;
+ }
+
+ for (i = 0; i < TLP_SRC_TOTAL_FIELDS; i++)
+ if (tlp_str_start_with(line, tlp_src_fields[i].key))
+ return tlp_src_fields[i].func(line, src, started, file);
+
+ return TLP_FAILED;
+}
+
+tlp_result tlp_src_get_name(tlp_str line,
+ tlp_src *src,
+ int *started,
+ const char *file)
+{
+ tlp_char name[TLP_SRC_NAME_MAX];
+
+ if (*started)
+ {
+ tlp_error_msg("%s: tlpsrc cannot have two name directives", file);
+ return TLP_FAILED;
+ }
+
+ if (tlp_str_get_word(line + tlp_str_len(TLP_STR("name")),
+ name, TLP_SRC_NAME_MAX) == TLP_OK)
+ {
+ src->name = tlp_str_copy(name);
+ *started = 1;
+
+ return TLP_OK;
+ }
+ else
+ return TLP_FAILED;
+}
+
+tlp_result tlp_src_get_catalogue(tlp_str line,
+ tlp_src *src,
+ int *started,
+ const char *file)
+{
+ if (! *started)
+ {
+ tlp_error_msg("%s: first tlpsrc directive must be 'name'", file);
+ return TLP_FAILED;
+ }
+
+ return TLP_OK;
+}
+
+/* }}} */
+
+/* tlp_pattern related {{{ */
+
+void tlp_pattern_free(tlp_pattern *pat)
+{
+ if (pat != NULL)
+ return;
+
+ switch (pat->type)
+ {
+ case TLP_PATTERN_T:
+ tlp_str_list_free(pat->u.t);
+ break;
+
+ case TLP_PATTERN_F:
+ tlp_str_free(pat->u.f);
+ break;
+
+ case TLP_PATTERN_D:
+ tlp_str_free(pat->u.d);
+ break;
+
+ case TLP_PATTERN_R:
+ tlp_str_free(pat->u.r);
+ break;
+ }
+
+ free(pat);
+ pat = NULL;
+}
+
+void tlp_patterns_free(tlp_pattern *pat)
+{
+ tlp_pattern *node = pat, *temp;
+
+ while (node != NULL)
+ {
+ temp = node->next;
+ tlp_pattern_free(node);
+ node = temp;
+ }
+
+ pat = NULL;
+}
+
+/* }}} */
+
+/* remaining stuff used in tlp_src processing {{{ */
+
+tlp_result tlp_str_get_word(tlp_str str, tlp_str word, int max)
+{
+ int i, j;
+
+ /* skip all leading spaces */
+ for (i = 0; tlp_char_is_space(str[i]); i++)
+ ;
+
+ j = 0;
+ for (; ! tlp_char_is_eol(str[i]); i++)
+ {
+ if (str[i] != TLP_CHAR('-') &&
+ ! tlp_char_in_word(str[i]))
+ return TLP_FAILED;
+
+ if (j >= max)
+ return TLP_FAILED;
+
+ word[j++] = str[i];
+ }
+
+ if (j == 0)
+ return TLP_FAILED;
+
+ word[j] = TLP_CHAR_END;
+ return TLP_OK;
+}
+
+/* }}} */
+
+/* vim:set ts=4 sts=4 sw=4 expandtab foldmethod=marker: */
diff --git a/Master/tlpkg/lib/C/tlp-src.h b/Master/tlpkg/lib/C/tlp-src.h
new file mode 100644
index 00000000000..cf04de32dc7
--- /dev/null
+++ b/Master/tlpkg/lib/C/tlp-src.h
@@ -0,0 +1,75 @@
+/* tlp-src.h - header for using tlpsrc files
+ *
+ * Copyright 2007 Jjgod Jiang
+ * Derived from the Perl implementation by Norbert Preining
+ *
+ * This file is licensed under the GNU General Public License version 2
+ * or any later version. */
+
+#ifndef __TLP_SRC__
+#define __TLP_SRC__
+
+#include <tlp-utils.h>
+
+enum tlp_src_limits {
+ TLP_SRC_LINE_MAX = 1024,
+ TLP_SRC_NAME_MAX = 256,
+};
+
+enum tlp_pattern_type {
+ TLP_PATTERN_T, TLP_PATTERN_F,
+ TLP_PATTERN_D, TLP_PATTERN_R
+};
+
+typedef struct tlp_pattern {
+ enum tlp_pattern_type type;
+
+ union {
+ tlp_str_list *t;
+ tlp_str f;
+ tlp_str d;
+ tlp_str r;
+ } u;
+
+ struct tlp_pattern *next;
+} tlp_pattern;
+
+typedef struct tlp_src {
+ /* name of the package */
+ tlp_str name;
+ /* Collection Scheme TLCore Package Documentation */
+ tlp_str category;
+ /* short one line desc */
+ tlp_str shortdesc;
+ /* longer multiline dscription */
+ tlp_str longdesc;
+ /* name of the respective Catalogue entry */
+ tlp_str catalogue;
+
+ tlp_pattern *runpatterns;
+ tlp_pattern *srcpatterns;
+ tlp_pattern *docpatterns;
+ tlp_pattern *binpatterns;
+
+ tlp_execute *executes;
+ tlp_depend *depends;
+} tlp_src;
+
+tlp_src *tlp_src_new(tlp_str name,
+ tlp_str category,
+ tlp_str shortdesc,
+ tlp_str longdesc,
+ tlp_str catalogue,
+ tlp_pattern *runpatterns,
+ tlp_pattern *srcpatterns,
+ tlp_pattern *docpatterns,
+ tlp_pattern *binpatterns,
+ tlp_execute *executes,
+ tlp_depend *depends);
+
+void tlp_src_free(tlp_src *src);
+void tlp_patterns_free(tlp_pattern *pat);
+void tlp_pattern_free(tlp_pattern *pat);
+
+#endif
+
diff --git a/Master/tlpkg/lib/C/tlp-utils.c b/Master/tlpkg/lib/C/tlp-utils.c
new file mode 100644
index 00000000000..5d24cfa42c9
--- /dev/null
+++ b/Master/tlpkg/lib/C/tlp-utils.c
@@ -0,0 +1,98 @@
+/* tlp-utils.h - module for general tlp utilities
+ *
+ * Copyright 2007 Jjgod Jiang
+ * Derived from the Perl implementation by Norbert Preining
+ *
+ * This file is licensed under the GNU General Public License version 2
+ * or any later version. */
+
+#include <tlp-utils.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+tlp_str tlp_str_copy(tlp_str str)
+{
+ if (str == NULL)
+ return NULL;
+
+ return strdup(str);
+}
+
+void tlp_str_free(tlp_str str)
+{
+ free(str);
+}
+
+void tlp_str_list_free(tlp_str_list *list)
+{
+ tlp_str_list *node = list, *temp;
+
+ while (node != NULL)
+ {
+ temp = node->next;
+
+ tlp_str_free(node->str);
+ free(node);
+
+ node = temp;
+ }
+
+ list = NULL;
+}
+
+tlp_str tlp_fgets(tlp_str s, int n, FILE *fp)
+{
+ return (tlp_str) fgets((char *) s, n, fp);
+}
+
+void tlp_str_output(FILE *fp, tlp_str str)
+{
+ fprintf(stderr, "%s", (char *) str);
+}
+
+size_t tlp_str_len(tlp_str str)
+{
+ return strlen((const char *) str);
+}
+
+int tlp_str_start_with(tlp_str str, tlp_str prefix)
+{
+ int len = tlp_str_len(prefix);
+
+ if (tlp_str_len(str) < len)
+ return 0;
+
+ return strncmp((const char *) str,
+ (const char *) prefix, len);
+}
+
+int tlp_char_is_space(tlp_char ch)
+{
+ return isspace((int) ch);
+}
+
+int tlp_char_is_eol(tlp_char ch)
+{
+ return (ch == '\r' || ch == '\n');
+}
+
+int tlp_char_in_word(tlp_char ch)
+{
+ return (isalnum(ch) || ch == '_');
+}
+
+void tlp_error_msg(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+void tlp_error_str(tlp_str str)
+{
+ tlp_str_output(stderr, str);
+}
+
diff --git a/Master/tlpkg/lib/C/tlp-utils.h b/Master/tlpkg/lib/C/tlp-utils.h
new file mode 100644
index 00000000000..9a05bb03086
--- /dev/null
+++ b/Master/tlpkg/lib/C/tlp-utils.h
@@ -0,0 +1,61 @@
+/* tlp-utils.h - header for general tlp definitions
+ *
+ * Copyright 2007 Jjgod Jiang
+ * Derived from the Perl implementation by Norbert Preining
+ *
+ * This file is licensed under the GNU General Public License version 2
+ * or any later version. */
+
+#ifndef __TLP_UTILS__
+#define __TLP_UTILS__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+typedef char tlp_char;
+typedef tlp_char *tlp_str;
+
+#define TLP_CHAR(x) ((tlp_char) x)
+#define TLP_STR(x) ((tlp_str) x)
+
+enum tlp_special_chars {
+ TLP_CHAR_COMMENT = TLP_CHAR('#'),
+ TLP_CHAR_END = TLP_CHAR('\0'),
+};
+
+typedef struct tlp_str_list {
+ tlp_str str;
+ struct tlp_str_list *next;
+} tlp_str_list;
+
+typedef tlp_str_list tlp_execute;
+typedef tlp_str_list tlp_depend;
+
+#define tlp_executes_free(x) tlp_str_list_free(x)
+#define tlp_depends_free(x) tlp_str_list_free(x)
+
+typedef enum tlp_result {
+ TLP_FAILED = 0, TLP_OK = 1
+} tlp_result;
+
+#define tlp_new(x) ((x *) malloc(sizeof(x)))
+
+tlp_str tlp_str_copy(tlp_str str);
+void tlp_str_free(tlp_str str);
+void tlp_str_list_free(tlp_str_list *list);
+
+tlp_str tlp_fgets(tlp_str s, int n, FILE *fp);
+size_t tlp_str_len(tlp_str str);
+void tlp_str_output(FILE *fp, tlp_str str);
+int tlp_str_start_with(tlp_str str, tlp_str prefix);
+
+int tlp_char_is_space(tlp_char ch);
+int tlp_char_is_eol(tlp_char ch);
+int tlp_char_in_word(tlp_char ch);
+
+void tlp_error_msg(const char *fmt, ...);
+void tlp_error_str(tlp_str str);
+
+#endif
+