aboutsummaryrefslogtreecommitdiff
path: root/op
diff options
context:
space:
mode:
Diffstat (limited to 'op')
-rw-r--r--op/vos_File.c128
-rw-r--r--op/vos_File.h2
-rw-r--r--op/vos_Stmt.c78
-rw-r--r--op/vos_Stmt.h1
-rw-r--r--op/vos_StmtJoin.h1
-rw-r--r--op/vos_StmtSort.c66
-rw-r--r--op/vos_StmtSort.h1
7 files changed, 220 insertions, 57 deletions
diff --git a/op/vos_File.c b/op/vos_File.c
index dfb80cb..f6ccd07 100644
--- a/op/vos_File.c
+++ b/op/vos_File.c
@@ -32,6 +32,8 @@ int file_open(struct File **F, const char *f, int flag)
if ((*F)->d < 0) {
str_raw_copy(f, &_vos.e_sparm0);
+ free((*F));
+ (*F) = 0;
switch (errno) {
case ENOENT:
@@ -249,3 +251,129 @@ int file_raw_is_exist(const char *file)
return s;
}
+
+/**
+ * @desc: copy file 'from' to 'to'.
+ */
+int file_raw_copy(const char *from, const char *to)
+{
+ int s;
+ int fdin;
+ int fdout;
+ long int nread = 0;
+ long int nwrite = 0;
+ long int ntot = 0;
+ char *buf;
+
+ fdin = open(from, O_RDONLY);
+ if (fdin < 0)
+ return E_FILE_OPEN;
+
+ fdout = open(to, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fdout < 0) {
+ close(fdin);
+ return E_FILE_OPEN;
+ }
+
+ buf = (char *) calloc(_vos.file_buf_size, sizeof(char));
+ if (! buf) {
+ close(fdin);
+ close(fdout);
+ return E_MEM;
+ }
+
+ nread = read(fdin, buf, _vos.file_buf_size);
+ if (nread < 0) {
+ s = E_FILE_READ;
+ goto err;
+ }
+ while (nread > 0) {
+ do {
+ nwrite = write(fdout, &buf[ntot], nread);
+ if (nwrite < 0) {
+ s = E_FILE_WRITE;
+ goto err;
+ }
+ ntot += nwrite;
+ nread -= nwrite;
+ } while (nread > 0);
+
+ nwrite = 0;
+ ntot = 0;
+
+ nread = read(fdin, buf, _vos.file_buf_size);
+ if (nread < 0) {
+ s = E_FILE_READ;
+ goto err;
+ }
+ }
+
+ s = 0;
+err:
+ close(fdout);
+ close(fdin);
+ free(buf);
+ return s;
+}
+
+/**
+ * @desc: get directory name from path.
+ * path => dirname
+ * "/usr/lib" => "/usr"
+ * "/usr/" => "/"
+ * "usr" => "."
+ * "/" => "/"
+ * "." => "."
+ * ".." => ".."
+ *
+ * @return:
+ * < 0 : success.
+ * < E_MEM : fail.
+ */
+int file_raw_get_dirname(const char *path, char **dirname)
+{
+ int l = 0;
+ char *d = 0;
+
+ if (! path
+ || (path && strcmp(path, "..") == 0)) {
+ d = (char *) calloc(2, sizeof(char));
+ if (d)
+ d[0] = '.';
+ goto out;
+ }
+
+ l = strlen(path) - 1;
+
+ /* path : '/' */
+ if (l == 0 && path[0] == '/') {
+ d = (char *) calloc(2, sizeof(char));
+ if (d)
+ d[0] = '/';
+ goto out;
+ }
+
+ /* path : '/path///' */
+ while (l >= 0 && path[l] == '/')
+ l--;
+
+ while (l >= 0 && path[l] != '/')
+ l--;
+
+ if (l < 0) {
+ d = (char *) calloc(2, sizeof(char));
+ if (d)
+ d[0] = '.';
+ } else {
+ if (l == 0)
+ l++;
+ d = (char *) calloc(l + 1, sizeof(char));
+ if (d)
+ memcpy(d, path, l);
+ }
+
+out:
+ (*dirname) = d;
+
+ return d ? 0 : E_MEM;
+}
diff --git a/op/vos_File.h b/op/vos_File.h
index 90f8a22..6d98166 100644
--- a/op/vos_File.h
+++ b/op/vos_File.h
@@ -23,5 +23,7 @@ void file_close(struct File **F);
int file_raw_get_size(const char *file, unsigned long *fsize);
int file_raw_is_exist(const char *file);
+int file_raw_copy(const char *from, const char *to);
+int file_raw_get_dirname(const char *path, char **dirname);
#endif
diff --git a/op/vos_Stmt.c b/op/vos_Stmt.c
index 41fc13c..0ad0bbd 100644
--- a/op/vos_Stmt.c
+++ b/op/vos_Stmt.c
@@ -26,59 +26,26 @@ void stmt_add(struct Stmt **stmt, struct Stmt *new_stmt)
(*stmt)->last = new_stmt;
}
-struct Stmt * stmt_find_by_name(struct Stmt *stmt, const char *name)
+struct Stmt * stmt_find_by_name(struct Stmt *p, const char *name)
{
- int s = 0;
- struct Stmt *p = stmt->last;
-
while (p) {
switch (p->type) {
case STMT_LOAD:
- s = strcasecmp(p->in->filename, name);
- if (s == 0)
- return p;
-
- if (p->in->alias) {
- s = strcasecmp(p->in->alias, name);
- if (s == 0)
- return p;
- }
- break;
-
case STMT_SORT:
- s = strcasecmp(p->in->filename, name);
- if (s == 0)
+ if (strcasecmp(p->in->filename, name) == 0)
return p;
- if (p->in->alias) {
- s = strcasecmp(p->in->alias, name);
- if (s == 0)
- return p;
- }
- break;
-
- case STMT_CREATE:
- s = strcasecmp(p->out->filename, name);
- if (s == 0)
+ if (strcasecmp(p->in->alias, name) == 0)
return p;
-
- if (p->out->alias) {
- s = strcasecmp(p->out->alias, name);
- if (s == 0)
- return p;
- }
break;
+ case STMT_CREATE:
case STMT_JOIN:
- s = strcasecmp(p->out->filename, name);
- if (s == 0)
+ if (strcasecmp(p->out->filename, name) == 0)
return p;
- if (p->out->alias) {
- s = strcasecmp(p->out->alias, name);
- if (s == 0)
- return p;
- }
+ if (strcasecmp(p->out->alias, name) == 0)
+ return p;
break;
}
p = p->prev;
@@ -87,6 +54,37 @@ struct Stmt * stmt_find_by_name(struct Stmt *stmt, const char *name)
return 0;
}
+/**
+ * @desc: update the filename in 'smeta' to point to sort output.
+ *
+ * some statement use sort output as input, since sort output some time
+ * is not defined in script (without INTO clause) then we need to update
+ * the filename before processing.
+ *
+ * @return:
+ * < 0 : success.
+ * < E_FILE_NOT_EXIST : fail, could not find file alias in 'stmt'.
+ */
+int stmt_update_meta(struct Stmt *stmt, struct StmtMeta *smeta)
+{
+ struct Stmt *p;
+
+ if (smeta->filename)
+ return 0;
+
+ p = stmt_find_by_name(stmt, smeta->alias);
+ if (! p) {
+ str_raw_copy(smeta->alias, &_vos.e_sparm0);
+ return E_FILE_NOT_EXIST;
+ }
+
+ if (p->type == STMT_SORT) {
+ str_raw_copy(p->out->filename, &smeta->filename);
+ }
+
+ return 0;
+}
+
void stmt_print(struct Stmt *stmt)
{
while (stmt) {
diff --git a/op/vos_Stmt.h b/op/vos_Stmt.h
index cbd589b..17a001a 100644
--- a/op/vos_Stmt.h
+++ b/op/vos_Stmt.h
@@ -13,6 +13,7 @@ extern const char *_stmt_type[N_STMT_TYPE];
void stmt_add(struct Stmt **stmt, struct Stmt *new_stmt);
struct Stmt * stmt_find_by_name(struct Stmt *stmt, const char *name);
+int stmt_update_meta(struct Stmt *stmt, struct StmtMeta *smeta);
void stmt_print(struct Stmt *stmt);
void stmt_destroy(struct Stmt **stmt);
diff --git a/op/vos_StmtJoin.h b/op/vos_StmtJoin.h
index a360f91..7267492 100644
--- a/op/vos_StmtJoin.h
+++ b/op/vos_StmtJoin.h
@@ -1,7 +1,6 @@
#ifndef _VOS_STMTJOIN_H
#define _VOS_STMTJOIN_H 1
-#include "type/vos_TStmtJoin.h"
#include "type/vos_TStmt.h"
#include "op/vos_StmtMeta.h"
#include "op/vos_File.h"
diff --git a/op/vos_StmtSort.c b/op/vos_StmtSort.c
index a2d4bc8..437feeb 100644
--- a/op/vos_StmtSort.c
+++ b/op/vos_StmtSort.c
@@ -8,7 +8,6 @@ int stmtsort_create(struct Stmt **sort)
(*sort)->out = (struct StmtMeta *) calloc(1, sizeof(struct StmtMeta));
if (! (*sort)->out) {
- free((*sort)->in);
free((*sort));
(*sort) = 0;
return E_MEM;
@@ -17,9 +16,9 @@ int stmtsort_create(struct Stmt **sort)
return 0;
}
-int stmtsort_init_output(struct Stmt *sort)
+int stmtsort_init(struct Stmt *sort)
{
- int s = E_MEM;
+ int s = 0;
struct Field *fld_in = 0;
struct Field *fld_out = 0;
@@ -30,18 +29,7 @@ int stmtsort_init_output(struct Stmt *sort)
return E_MEM;
}
- if (! sort->out->filename) {
- do {
- s = str_raw_randomize(VOS_SORT_OUT_FORMAT,
- &sort->out->filename);
- if (s)
- return s;
-
- s = file_raw_is_exist(sort->out->filename);
- if (s)
- free(sort->out->filename);
- } while (s);
- } else {
+ if (sort->out->filename) {
/* check if file output is exist */
s = file_raw_is_exist(sort->out->filename);
if (s) {
@@ -79,6 +67,49 @@ int stmtsort_init_output(struct Stmt *sort)
return 0;
}
+/**
+ * @stmtsort_init_output: get temporary file name for sort output.
+ *
+ * @return:
+ * < 0 : success.
+ * < !0 : fail.
+ */
+int stmtsort_init_output(struct Stmt *sort)
+{
+ int s;
+ char *rndm_name = 0;
+ struct String *tmp = 0;
+
+ /* filename already declared by INTO statement */
+ if (sort->out->filename)
+ return 0;
+
+ str_create(&tmp);
+
+ do {
+ str_append(tmp, get_tmp_dir(0));
+
+ s = str_raw_randomize(VOS_SORT_OUT_FORMAT, &rndm_name);
+ if (s)
+ goto err;
+
+ str_append(tmp, rndm_name);
+
+ s = file_raw_is_exist(tmp->buf);
+ if (s)
+ str_prune(tmp);
+
+ free(rndm_name);
+ } while (s);
+
+ sort->out->flag |= SORT_TMP;
+ sort->out->filename = tmp->buf;
+ tmp->buf = 0;
+err:
+ str_destroy(&tmp);
+ return s;
+}
+
void stmtsort_print(struct Stmt *sort)
{
if (! sort)
@@ -99,8 +130,11 @@ void stmtsort_destroy(struct Stmt **sort)
stmtmeta_soft_destroy(&(*sort)->in);
if ((*sort)->out) {
- if ((*sort)->out->filename)
+ if ((*sort)->out->filename) {
+ if ((*sort)->out->flag & SORT_TMP)
+ unlink((*sort)->out->filename);
free((*sort)->out->filename);
+ }
if ((*sort)->out->alias)
free((*sort)->out->alias);
field_soft_destroy(&(*sort)->out->fields);
diff --git a/op/vos_StmtSort.h b/op/vos_StmtSort.h
index e167876..4edbaff 100644
--- a/op/vos_StmtSort.h
+++ b/op/vos_StmtSort.h
@@ -8,6 +8,7 @@
#define sort_get_idx(T) get_token_idx(_fflag_sort, N_FFLAG_SORT, T)
int stmtsort_create(struct Stmt **sort);
+int stmtsort_init(struct Stmt *sort);
int stmtsort_init_output(struct Stmt *sort);
void stmtsort_print(struct Stmt *sort);
void stmtsort_destroy(struct Stmt **sort);