diff options
author | Jjgod Jiang <gzjjgod@gmail.com> | 2007-11-20 08:50:29 +0000 |
---|---|---|
committer | Jjgod Jiang <gzjjgod@gmail.com> | 2007-11-20 08:50:29 +0000 |
commit | 5e225d257c6d1f38a26a84ef299666eeaa676a9b (patch) | |
tree | 55347b7fe3d03f75fb19a46de6b373e043321071 /Master | |
parent | d9e6221bd1c00ef10da9a274657e35b922ba3e5d (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.c | 314 | ||||
-rw-r--r-- | Master/tlpkg/lib/C/tlp-src.h | 75 | ||||
-rw-r--r-- | Master/tlpkg/lib/C/tlp-utils.c | 98 | ||||
-rw-r--r-- | Master/tlpkg/lib/C/tlp-utils.h | 61 |
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 + |