static int ret_mask(sigset_t *mask, int arg_number) { // TODO; NODE *tmp, *array, *elm, *value; int i; int sig; array = (NODE *) get_array_argument(arg_number, FALSE); if ( array != NULL ) { #if 0 for (i = 0; i < array->array_size; i++) { for (elm = array->var_array[i]; elm != NULL; elm = elm->ahnext) { name = elm->hname; force_string(name); sig = str2sig(name->stptr); if (sig) { value = elm->hvalue; force_string(value); if (value->stptr[0] != '0' && value->stptr[0] != '\0') { sigaddset(mask, sig); } } } } #endif } else { tmp = (NODE *) get_scalar_argument(arg_number, FALSE); } return 0; }
// 材質 NODE * do_Material(int nargs) { NODE *tmp; GLenum face; GLenum pname; float params[8]; int param_num; int i; tmp = (NODE*) get_actual_argument(0, FALSE, FALSE); force_string(tmp); face = material_face(tmp->stptr); tmp = (NODE*) get_actual_argument(1, FALSE, FALSE); force_string(tmp); pname = material_pname(tmp->stptr); switch (pname) { case GL_SHININESS: param_num = 1; break; case GL_COLOR_INDEXES: param_num = 3; break; case GL_AMBIENT_AND_DIFFUSE: param_num = 8; break; default: param_num = 4; break; } for (i = 0; i < param_num; i++) { tmp = (NODE*) get_actual_argument(i + 2, FALSE, FALSE); params[i] = (GLfloat) force_number(tmp); } // OpenGLで質感を設定するときは、通常glMaterialfv()を使います。 // いままで使ってきた、glColor3fv()と同様に、図形を描く前に質感を設定するという手順をとります。 // OpenGLのポリゴンには、表と裏という概念があって、faceはそのどちらの面の質感を設定するかを指定する。 // GL_FRONT(表)、GL_BACK(裏)、GL_FRONT_AND_BACK(両方)のうちのいずれか。 // 今回は、ひとまずGL_FRONT_AND_BACKを指定しておいた。 // ポリゴンの表裏に関しては、他の機会に説明する。 // pnameは、質感のどのパラメタを設定するかを指定する。 // GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_EMISSION、GL_SHININESSなどがあり、このうちの1つを選んで設定する。 // それぞれ、質感についてで解説した通り。 // paramsには、実際に設定する値の入った配列を渡す。 // GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_EMISSIONの場合は、RGBA形式である。 // それぞれ、─1から1の範囲の値を入れる。 // GL_SHININESSの場合は、渡す値は1つで、0から128の範囲の値である。 // GL_SHINESSを設定するだけなら、glMaterialf()を使うこともできる。 // //void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) glMaterialfv(face, pname, params); return make_number((AWKNUM) 0); }
int cmp_nodes(NODE *t1, NODE *t2) { int ret = 0; size_t len1, len2; int l, ldiff; if (t1 == t2) return 0; if (t1->flags & MAYBE_NUM) (void) force_number(t1); if (t2->flags & MAYBE_NUM) (void) force_number(t2); if (t1->flags & INTIND) t1 = force_string(t1); if (t2->flags & INTIND) t2 = force_string(t2); if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) return cmp_numbers(t1, t2); (void) force_string(t1); (void) force_string(t2); len1 = t1->stlen; len2 = t2->stlen; ldiff = len1 - len2; if (len1 == 0 || len2 == 0) return ldiff; if (do_posix) return posix_compare(t1, t2); l = (ldiff <= 0 ? len1 : len2); if (IGNORECASE) { const unsigned char *cp1 = (const unsigned char *) t1->stptr; const unsigned char *cp2 = (const unsigned char *) t2->stptr; #if MBS_SUPPORT if (gawk_mb_cur_max > 1) { ret = strncasecmpmbs((const unsigned char *) cp1, (const unsigned char *) cp2, l); } else #endif /* Could use tolower() here; see discussion above. */ for (ret = 0; l-- > 0 && ret == 0; cp1++, cp2++) ret = casetable[*cp1] - casetable[*cp2]; } else ret = memcmp(t1->stptr, t2->stptr, l); ret = ret == 0 ? ldiff : ret; return ret; }
static int ana_flags(int arg_number) { NODE *tmp, *array, *elm, *value; int i; int flag; int flags = 0; array = (NODE *) get_array_argument(arg_number, FALSE); if ( array != NULL ) { for (i = 0; i < array->array_size; i++) { for (elm = array->var_array[i]; elm != NULL; elm = elm->ahnext) { flag = str2flag(elm->hname); if (flag) { value = elm->hvalue; force_string(value); if (value->stptr[0] != '0' && value->stptr[0] != '\0') { flags |= flag; } } } } } else { tmp = (NODE *) get_scalar_argument(arg_number, FALSE); if (tmp->stptr[0] == '\0') { flags |= SA_RESTART; /* システムコールが中止しない */ } else { //TODO; } } return 0; }
static NODE * fetch_SYS(NODE *symbol, NODE *subs, void *data) { force_string(subs); if (strcmp(subs->stptr, "time") == 0) return do_strftime(0); return NULL; }
static void load_READLINE(NODE *symbol, void *data) { sdata_t *sd = (sdata_t *) data; NODE *file, *tmp; FILE *fp; static char linebuf[BUFSIZ]; int i; bool long_line = false; if (! sd->load_file) /* non-existent SYS["readline"] or already loaded */ return; file = sd->filename; force_string(file); if (file->stlen == 0) return; assoc_clear(symbol); if ((fp = fopen(file->stptr, "r" )) == NULL) { warning(_("READLINE (%s): %s"), file->stptr, strerror(errno)); return; } for (i = 1; fgets(linebuf, sizeof(linebuf), fp ) != NULL; i++) { NODE **lhs; size_t sz; sz = strlen(linebuf); if (sz > 0 && linebuf[sz - 1] == '\n') { linebuf[sz - 1] = '\0'; sz--; if (long_line) { long_line = false; i--; continue; } } else if (long_line) { i--; continue; } else { if (do_lint) lintwarn(_("file `%s' does not end in newline or line # `%d' is too long"), file->stptr, i); long_line = true; } tmp = make_number(i); lhs = assoc_lookup(symbol, tmp); unref(tmp); unref(*lhs); *lhs = make_string(linebuf, sz); } fclose(fp); sd->load_file = false; /* don't load this file again */ }
static int get_signo(NODE *tmp) { int sig; force_string(tmp); sig = str2sig(tmp->stptr); if (sig == 0) { sig = num2sig((int) force_number(tmp)); } if (sig == 0) { force_string(tmp); fatal(_("Signal `%s' is not defined"), tmp->stptr); } return sig; }
NODE * do_BitmapLength(int nargs) { NODE *tmp; void *font; const unsigned char *string; tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); if ((font = str2font(tmp->stptr)) == NULL) { // TODO } tmp = (NODE *) get_scalar_argument(1, FALSE); force_string(tmp); string = (const unsigned char *) tmp->stptr; //TODO cast return make_number((AWKNUM) glutBitmapLength(font, string)); }
NODE * do_StrokeString(int nargs) { NODE *tmp; void *font; const unsigned char *string; tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); if ((font = str2font(tmp->stptr)) == NULL) { // TODO } tmp = (NODE *) get_scalar_argument(1, FALSE); force_string(tmp); string = (const unsigned char *) tmp->stptr; glutStrokeString(font, string); return make_number((AWKNUM) 0); }
Regexp * re_update(NODE *t) { NODE *t1; if ((t->re_flags & CASE) == IGNORECASE) { if ((t->re_flags & CONST) != 0) { assert(t->type == Node_regex); return t->re_reg; } t1 = force_string(tree_eval(t->re_exp)); if (t->re_text != NULL) { if (cmp_nodes(t->re_text, t1) == 0) { free_temp(t1); return t->re_reg; } unref(t->re_text); } t->re_text = dupnode(t1); free_temp(t1); } if (t->re_reg != NULL) refree(t->re_reg); if (t->re_cnt > 0) t->re_cnt++; if (t->re_cnt > 10) t->re_cnt = 0; if (t->re_text == NULL || (t->re_flags & CASE) != IGNORECASE) { t1 = force_string(tree_eval(t->re_exp)); unref(t->re_text); t->re_text = dupnode(t1); free_temp(t1); } t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen, IGNORECASE, t->re_cnt); t->re_flags &= ~CASE; t->re_flags |= IGNORECASE; return t->re_reg; }
NODE * do_BitmapWidth(int nargs) { NODE *tmp; void *font; int character; tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); if ((font = str2font(tmp->stptr)) == NULL) { // TODO } tmp = (NODE *) get_scalar_argument(1, FALSE); force_string(tmp); if (tmp->stlen != 1) { // TODO } character = (int) tmp->stptr[0]; return make_number((AWKNUM) glutBitmapWidth(font, character)); }
static NODE * do_writea(int nargs) { NODE *file, *array; int ret; int fd; uint32_t major = MAJOR; uint32_t minor = MINOR; if (do_lint && get_curfunc_arg_count() > 2) lintwarn("writea: called with too many arguments"); /* directory is first arg, array to dump is second */ file = get_scalar_argument(0, FALSE); array = get_array_argument(1, FALSE); /* open the file, if error, set ERRNO and return */ (void) force_string(file); fd = creat(file->stptr, 0600); if (fd < 0) { goto done1; } if (write(fd, MAGIC, strlen(MAGIC)) != strlen(MAGIC)) goto done1; major = htonl(major); if (write(fd, & major, sizeof(major)) != sizeof(major)) goto done1; minor = htonl(minor); if (write(fd, & minor, sizeof(minor)) != sizeof(minor)) goto done1; ret = write_array(fd, array); if (ret != 0) goto done1; ret = 0; goto done0; done1: ret = -1; update_ERRNO(); unlink(file->stptr); done0: close(fd); /* Set the return value */ return make_number((AWKNUM) ret); }
static void store_SYS(NODE *symbol, NODE *subs, NODE *val, void *data) { sdata_t *sd = (sdata_t *) data; if (subs != NULL && val != NULL && val->type == Node_val) { force_string(subs); if (strcmp(subs->stptr, "readline") == 0) { sd->load_file = true; unref(sd->filename); sd->filename = dupnode(val); } } }
NODE * do_BitmapHeight(int nargs) { NODE *tmp; void *font; tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); if ((font = str2font(tmp->stptr)) == NULL) { // TODO } return make_number((AWKNUM) glutBitmapHeight(font)); }
// 光源 NODE * do_Light(int nargs) { NODE *tmp; GLenum light; GLenum pname; float params[4]; int param_num; int i; //tmp = (NODE*) get_actual_argument(0, FALSE, FALSE); //force_string(tmp); //light = light_light_s(tmp->stptr); tmp = (NODE*) get_actual_argument(0, FALSE, FALSE); light = light_light_n((int) force_number(tmp)); tmp = (NODE*) get_actual_argument(1, FALSE, FALSE); force_string(tmp); pname = light_pname(tmp->stptr); switch (pname) { case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION: param_num = 4; break; case GL_SPOT_DIRECTION: param_num = 3; break; default: param_num = 1; break; } for (i = 0; i < param_num; i++) { tmp = (NODE*) get_actual_argument(i + 2, FALSE, FALSE); params[i] = (GLfloat) force_number(tmp); } // void glLightfv( GLenum light , GLenum pname , const GLfloat *params ); glLightfv(light, pname , params); return make_number((AWKNUM) 0); }
static NODE * do_sigprocmask(int nargs) { NODE *tmp; int how; sigset_t mask; sigset_t old; int ret; if (do_lint && get_curfunc_arg_count() > 1) lintwarn("sigsuspend: called with too many arguments"); tmp = (NODE *) get_scalar_argument(0, FALSE); force_string(tmp); how = str2how(tmp->stptr); ana_mask(&mask, 1); ret = sigprocmask(how, &mask, &old); ret_mask(&mask, 2); return make_number((AWKNUM) ret); }
static int ana_mask(sigset_t *mask, int arg_number) { NODE *tmp, *array, *elm, *name, *value; int i; int sig; sigemptyset(mask); array = (NODE *) get_array_argument(arg_number, FALSE); if ( array != NULL ) { for (i = 0; i < array->array_size; i++) { for (elm = array->var_array[i]; elm != NULL; elm = elm->ahnext) { sig = str2sig(elm->hname); if (sig) { value = elm->hvalue; force_string(value); if (value->stptr[0] != '0' && value->stptr[0] != '\0') { sigaddset(mask, sig); } } } } } else { tmp = (NODE *) get_scalar_argument(arg_number, FALSE); if (strcmp(tmp->stptr, "@all") == 0) { // toupper TODO @FILL sigfillset(mask); } else if (strcmp(tmp->stptr, "@empty") == 0) { // TODO sigemptyset(mask); } else { } } return 0; }
static NODE * do_select(int nags) { NODE *tmp, *array, *elm, *value; int nfds; fd_set rfds, wfds, efds; struct timeval timeout; struct timeval *timeout_ptr; int retval; struct redirect *rp; double integer, point; int i, j; int fp; if (do_lint && get_curfunc_arg_count() > 4) lintwarn("select: called with too many arguments"); /*** Analyse File-descriptors ***/ nfds = -1; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); for (i = 0; i < 3; i++ ) { array = (NODE *) get_array_argument(i, FALSE); if ( array == NULL ) { continue; } for (j = 0; j < array->array_size; j++) { for (elm = array->var_array[j]; elm != NULL; elm = elm->ahnext) { value = elm->hvalue; force_string(value); rp = getredirect(value->stptr, value->stlen); if (rp == NULL) { if (do_lint) { lintwarn("select: `%.*s' is not an open file, pipe or co-process", (int) value->stlen, value->stptr); } } fp = fileno(rp->fp); switch (i) { case 0: FD_SET(fp, &rfds); break; case 1: FD_SET(fp, &wfds); break; case 2: FD_SET(fp, &efds); break; } if (fp + 1 > nfds ) { nfds = fp + 1; } } } } /*** Analyse Timeout ***/ /* timeout specified as milli-seconds */ tmp = (NODE *) get_actual_argument(3, FALSE, FALSE); point = modf(force_number(tmp), &integer); if (integer < 0) { timeout_ptr = NULL; } else { timeout.tv_sec = (time_t) (integer / 1000); timeout.tv_usec = (suseconds_t) (point * 1000); timeout_ptr = &timeout; } retval = select(nfds, &rfds, &wfds, &efds, timeout_ptr); if (retval == -1) { perror("select()"); } else if (retval != 0) { /* TODO */ } return make_number((AWKNUM) retval); }
static NODE * do_signal(int nargs) { NODE *tmp; const char *str; int sig; NODE *fnc_ptr; SigTable *sig_tbl; struct sigaction sig_act; if (do_lint && get_curfunc_arg_count() > 4) lintwarn("signal: called with too many arguments"); memset(&sig_act, 0, sizeof(struct sigaction)); /* signal number */ tmp = (NODE *) get_scalar_argument(0, FALSE); sig = get_signo(tmp); /* signal handler */ tmp = (NODE *) get_scalar_argument(1, FALSE); force_string(tmp); str = tmp->stptr; sig_tbl = sig2ptr(sig); if (str[0] == '@') { str++; /* advance '@' */ if (strncmp(str, "SIG", 3) == 0) { str += 3; } if (strncmp(str, "_", 1) == 0) { str += 1; } if (strcmp(str, "DFL") == 0) { sig_act.sa_handler = SIG_DFL; } else if (strcmp(str, "IGN") == 0) { sig_act.sa_handler = SIG_IGN; } else { //TODO sig_act.sa_handler = SIG_IGN; fatal } sig_tbl->user_handler = NULL; } else { fnc_ptr = lookup(str); sig_tbl->user_handler = fnc_ptr; sig_act.sa_handler = handler; } if (fnc_ptr == NULL || fnc_ptr->type != Node_func) fatal(_("Callback function `%s' is not defined"), tmp->stptr); /* mask */ if (get_curfunc_arg_count() >= 3) ana_mask(&sig_act.sa_mask, 2); else sigfillset(&sig_act.sa_mask); /* flags */ if (get_curfunc_arg_count() >= 4) sig_act.sa_flags = ana_flags(3); else sig_act.sa_flags |= SA_RESTART; /* システムコールが中止しない */ return make_number((AWKNUM) sigaction(sig, &sig_act, NULL)); }
static NODE * do_reada(int nargs) { NODE *file, *array; int ret; int fd; uint32_t major; uint32_t minor; char magic_buf[30]; if (do_lint && get_curfunc_arg_count() > 2) lintwarn("reada: called with too many arguments"); /* directory is first arg, array to dump is second */ file = get_scalar_argument(0, FALSE); array = get_array_argument(1, FALSE); (void) force_string(file); fd = open(file->stptr, O_RDONLY); if (fd < 0) { goto done1; } memset(magic_buf, '\0', sizeof(magic_buf)); if (read(fd, magic_buf, strlen(MAGIC)) != strlen(MAGIC)) { goto done1; } if (strcmp(magic_buf, MAGIC) != 0) { goto done1; } if (read(fd, & major, sizeof(major)) != sizeof(major)) { goto done1; } major = ntohl(major); if (major != MAJOR) { goto done1; } if (read(fd, & minor, sizeof(minor)) != sizeof(minor)) { goto done1; } minor = ntohl(minor); if (minor != MINOR) { goto done1; } assoc_clear(array); ret = read_array(fd, array); if (ret == 0) goto done0; done1: ret = -1; update_ERRNO(); done0: close(fd); /* Set the return value */ return make_number((AWKNUM) ret); }
static NODE * can_sub(int mode) { NODE *tmp; int nfds; fd_set fds; struct timeval timeout; struct timeval *timeout_ptr; int retval; struct redirect *rp; double integer, point; /*** Analyse File-descriptor ***/ tmp = (NODE *) get_actual_argument(0, FALSE, FALSE); force_string(tmp); rp = getredirect(tmp->stptr, tmp->stlen); if (rp == NULL) { /* no match, return -1 */ if (do_lint) { const char *fn; switch (mode) { case CAN_READ: fn = "can_read"; break; case CAN_WRITE: fn = "can_write"; break; case HAS_EXCEPTION: fn = "has_excepstion"; break; } lintwarn("%s: `%.*s' is not an open file, pipe or co-process", fn, (int) tmp->stlen, tmp->stptr); } return make_number((AWKNUM) 0); } nfds = fileno(rp->fp) + 1; FD_ZERO(&fds); FD_SET(fileno(rp->fp), &fds); /*** Analyse Timeout ***/ /* timeout specified as milli-seconds */ tmp = (NODE *) get_actual_argument(1, FALSE, FALSE); point = modf(force_number(tmp), &integer); if (integer < 0) { timeout_ptr = NULL; } else { timeout.tv_sec = (time_t) (integer / 1000); timeout.tv_usec = (suseconds_t) (point * 1000); timeout_ptr = &timeout; } switch (mode) { case CAN_READ: retval = select(nfds, &fds, NULL, NULL, timeout_ptr); break; case CAN_WRITE: retval = select(nfds, NULL, &fds, NULL, timeout_ptr); break; case HAS_EXCEPTION: retval = select(nfds, NULL, NULL, &fds, timeout_ptr); break; } if (retval == -1) perror("select()"); return make_number((AWKNUM) retval); }