/* * FUNCTION qsub(char *qtag, int flags) * * based on the settings of flags, and the template file $QDIR/qtag.sql * make the following substitutions to turn a query template into EQT * * String Converted to Based on * ====== ============ =========== * first line database <db_name>; -n from command line * second line set explain on; -x from command line * :<number> parameter <number> * :k set number * :o output to outpath/qnum.snum * -o from command line, SET_OUTPUT * :s stream number * :b BEGIN WORK; -a from command line, START_TRAN * :e COMMIT WORK; -a from command line, END_TRAN * :q query number * :n<number> sets rowcount to be returned */ void qsub(char *qtag, int flags) { static char *line = NULL, *qpath = NULL; FILE *qfp; char *cptr, *mark, *qroot = NULL; qnum = atoi(qtag); if (line == NULL) { line = malloc(BUFSIZ); qpath = malloc(BUFSIZ); MALLOC_CHECK(line); MALLOC_CHECK(qpath); } qroot = env_config(QDIR_TAG, QDIR_DFLT); sprintf(qpath, "%s%c%s.sql", qroot, PATH_SEP, qtag); qfp = fopen(qpath, "r"); OPEN_CHECK(qfp, qpath); rowcnt = rowcnt_dflt[qnum]; varsub(qnum, 0, flags); /* set the variables */ if (flags & DFLT_NUM) fprintf(ofp, SET_ROWCOUNT, rowcnt); while (fgets(line, BUFSIZ, qfp) != NULL) { if (!(flags & COMMENT)) strip_comments(line); mark = line; while ((cptr = strchr(mark, VTAG)) != NULL) { *cptr = '\0'; cptr++; fprintf(ofp,"%s", mark); switch(*cptr) { case 'b': case 'B': if (!(flags & ANSI)) fprintf(ofp,"%s\n", START_TRAN); cptr++; break; case 'c': case 'C': if (flags & DBASE) fprintf(ofp, SET_DBASE, db_name); cptr++; break; case 'e': case 'E': if (!(flags & ANSI)) fprintf(ofp,"%s\n", END_TRAN); cptr++; break; case 'n': case 'N': if (!(flags & DFLT_NUM)) { rowcnt=atoi(++cptr); while (isdigit(*cptr) || *cptr == ' ') cptr++; fprintf(ofp, SET_ROWCOUNT, rowcnt); } continue; case 'o': case 'O': if (flags & OUTPUT) fprintf(ofp,"%s '%s/%s.%d'", SET_OUTPUT, osuff, qtag, (snum < 0)?0:snum); cptr++; break; case 'q': case 'Q': fprintf(ofp,"%s", qtag); cptr++; break; case 's': case 'S': fprintf(ofp,"%d", (snum < 0)?0:snum); cptr++; break; case 'X': case 'x': if (flags & EXPLAIN) fprintf(ofp, "%s\n", GEN_QUERY_PLAN); cptr++; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': varsub(qnum, atoi(cptr), flags & DFLT); while (isdigit(*++cptr)); break; default: fprintf(stderr, "-- unknown flag '%c%c' ignored\n", VTAG, *cptr); cptr++; break; } mark=cptr; } fprintf(ofp,"%s", mark); } fclose(qfp); fflush(stdout); return; }
//! //! Main entry point of the application //! //! @param[in] argc the number of parameter passed on the command line //! @param[in] argv the list of arguments //! //! @return EUCA_OK on success or EUCA_ERROR on failure. //! int main(int argc, char **argv) { char *c_s1_sub = NULL; char *c_s2_sub = NULL; char *c_s3_sub = NULL; wchar_t *s1_sub = NULL; wchar_t *s2_sub = NULL; wchar_t *s3_sub = NULL; setlocale(LC_ALL, "en_US.UTF-8"); m = varmap_alloc(NULL, L"color", L"brown"); m = varmap_alloc(m, L"subject", L"føx"); m = varmap_alloc(m, L"øbject", L"dog"); printf(" nice string: %ls\n", s1); s1_sub = varsub(s1, (const wchar_map **)m); assert(s1_sub != NULL); printf("nice string subbed: %ls\n", s1_sub); EUCA_FREE(s1_sub); printf(" ugly string: %ls\n", s2); s2_sub = varsub(s2, (const wchar_map **)m); assert(s2_sub != NULL); printf("ugly string subbed: %ls\n", s2_sub); EUCA_FREE(s2_sub); printf(" unsubbable string: %ls\n", s3); assert(varsub(s3, (const wchar_map **)m) == NULL); varmap_free(m); printf(" sending null map: %ls\n", s3); // Reuse s3 s3_sub = varsub(s3, NULL); printf("returned from null: %ls\n", s3_sub); EUCA_FREE(s3_sub); // Now do it again, this time non-widechar c_m = c_varmap_alloc(NULL, "colorxxxxxx", "brown"); //! @todo This matches c_m = c_varmap_alloc(c_m, "subject", "fox"); c_m = c_varmap_alloc(c_m, "object", "dog"); printf(" nice string: %s\n", c_s1); c_s1_sub = c_varsub(c_s1, (const char_map **)c_m); printf("nice string subbed: %s\n", c_s1_sub); assert(c_s1_sub != NULL); EUCA_FREE(c_s1_sub); printf(" ugly string: %s\n", c_s2); c_s2_sub = c_varsub(c_s2, (const char_map **)c_m); assert(c_s2_sub != NULL); printf("ugly string subbed: %s\n", c_s2_sub); EUCA_FREE(c_s2_sub); printf(" unsubbable string: %s\n", c_s3); c_s3_sub = c_varsub(c_s3, (const char_map **)c_m); printf(" unsubbed string: %s\n", c_s3_sub); assert(!strcmp(c_s3, c_s3_sub)); EUCA_FREE(c_s3_sub); c_varmap_free(c_m); printf(" sending null map: %s\n", c_s3); // Reuse s3 c_s3_sub = c_varsub(c_s3, NULL); printf("returned from null: %s\n", c_s3_sub); assert(!strcmp(c_s3, c_s3_sub)); EUCA_FREE(c_s3_sub); }
extern List *glom(Node *n) { List *v, *head, *tail; Node *words; if (n == NULL) return NULL; switch (n->type) { case nArgs: case nLappend: words = n->u[0].p; tail = NULL; while (words != NULL && (words->type == nArgs || words->type == nLappend)) { if (words->u[1].p != NULL && words->u[1].p->type != nWord) break; head = glom(words->u[1].p); if (head != NULL) { head->n = tail; tail = head; } words = words->u[0].p; } v = append(glom(words), tail); /* force left to right evaluation */ return append(v, glom(n->u[1].p)); case nBackq: return backq(n->u[0].p, n->u[1].p); case nConcat: head = glom(n->u[0].p); /* force left-to-right evaluation */ return concat(head, glom(n->u[1].p)); case nDup: case nRedir: qredir(n); return NULL; case nWord: return word(n->u[0].s, n->u[1].s); case nNmpipe: return mkcmdarg(n); default: /* The next four operations depend on the left-child of glom to be a variable name. Therefore the variable is looked up here. */ if ((v = glom(n->u[0].p)) == NULL) rc_error("null variable name"); if (v->n != NULL) rc_error("multi-word variable name"); if (*v->w == '\0') rc_error("zero-length variable name"); v = (*v->w == '*' && v->w[1] == '\0') ? varlookup(v->w)->n : varlookup(v->w); switch (n->type) { default: panic("unexpected node in glom"); exit(1); /* NOTREACHED */ case nCount: return count(v); case nFlat: return flatten(v); case nVar: return v; case nVarsub: return varsub(v, glom(n->u[1].p)); } } }