diff options
Diffstat (limited to 'noao/astutil/t_asthedit.x')
-rw-r--r-- | noao/astutil/t_asthedit.x | 561 |
1 files changed, 561 insertions, 0 deletions
diff --git a/noao/astutil/t_asthedit.x b/noao/astutil/t_asthedit.x new file mode 100644 index 00000000..51cf2796 --- /dev/null +++ b/noao/astutil/t_asthedit.x @@ -0,0 +1,561 @@ +include <error.h> +include <fset.h> +include <evvexpr.h> +include <ctype.h> +include <ctotok.h> +include <lexnum.h> +include <imset.h> +include <time.h> +include "astfunc.h" + +define SZ_KEY 8 +define SPECIAL "|if|else|endif|print|printf|quit|" + + +# T_ASTHEDIT -- Edit/calculator keywords in an image header including +# astronomical routines. + +procedure t_asthedit() + +int imlist # list of images +pointer cmd # command file +pointer table # data table +pointer col # column names +pointer prompt # prompt for STDIN +bool update # update image header? +bool verbose # verbose output? +bool oldstyle # use old style without equals sign? + +bool eval +int i, ip, sz_cmd, fdcmd, ncmds, acmode, nim, tm[LEN_TMSTRUCT] +long pos +pointer sp, image, key, expr, keys, exprs, ast +pointer stopen() +int imtopenp(), imtlen(), imtgetim(), immap() +int open(), fscan(), fstati(), nowhite(), ctowrd(), ctotok() +int strlen(), stridxs(), strdic() +bool clgetb(), streq() +long note(), clktime(), lsttogmt() +errchk open, stopen, immap + +begin + call smark (sp) + call salloc (image, SZ_FNAME, TY_CHAR) + call salloc (table, SZ_FNAME, TY_CHAR) + call salloc (prompt, SZ_FNAME, TY_CHAR) + call salloc (col, SZ_LINE, TY_CHAR) + call salloc (key, SZ_KEY, TY_CHAR) + + sz_cmd = SZ_LINE + call malloc (cmd, sz_cmd, TY_CHAR) + call malloc (expr, sz_cmd, TY_CHAR) + + # Create ast_func data structure. + call calloc (ast, LEN_AST, TY_STRUCT) + + # Open symbol table for storing results. + AST_STP(ast) = stopen ("astcalc", 20, 1024, 20*SZ_KEY) + + # Open the image list and first image. + imlist = imtopenp ("images") + nim = imtlen (imlist) + if (imtgetim (imlist, Memc[image], SZ_FNAME) == EOF) { + call mktemp ("tmp$iraf", Memc[image], SZ_FNAME) + AST_IM(ast) = immap (Memc[image], NEW_IMAGE, 0) + } else { + update = clgetb ("update") + if (update) + acmode = READ_WRITE + else + acmode = READ_ONLY + repeat { + ifnoerr (AST_IM(ast) = immap (Memc[image], acmode, 0)) + break + call erract (EA_WARN) + if (imtgetim (imlist, Memc[image], SZ_FNAME) == EOF) { + call sfree (sp) + return + } + } + } + + # Open the command file. + ncmds = 0 + call clgstr ("commands", Memc[cmd], SZ_LINE) + if (nowhite (Memc[cmd], Memc[cmd], SZ_FNAME) > 0) { + fdcmd = open (Memc[cmd], READ_ONLY, TEXT_FILE) + Memc[prompt] = EOS + } else { + fdcmd = STDIN + call clgstr ("prompt", Memc[prompt], SZ_FNAME) + } + oldstyle = clgetb ("oldstyle") + + # Set conditional flag and verbose and print output. + eval = TRUE + call fseti (STDOUT, F_FLUSHNL, YES) + verbose = clgetb ("verbose") + if (verbose) { + call printf ("%s:\n") + call pargstr (Memc[image]) + } + + # Set special operands. + call sprintf (Memc[expr], sz_cmd, "\"%s\"") + call pargstr (Memc[image]) + call ah_evaluate (ast, "$I", Memc[expr], eval, verbose) + pos = clktime(0) + call brktime (pos, tm) + call sprintf (Memc[expr], sz_cmd, "\"%02d/%02d/%02d\"") + call pargi (TM_MDAY(tm)) + call pargi (TM_MONTH(tm)) + call pargi (mod (TM_YEAR(tm), 100)) + call ah_evaluate (ast, "$D", Memc[expr], eval, verbose) + call sprintf (Memc[expr], sz_cmd, "\"%02d:%02d:%02d\"") + call pargi (TM_HOUR(tm)) + call pargi (TM_MIN(tm)) + call pargi (TM_SEC(tm)) + call ah_evaluate (ast, "$T", Memc[expr], eval, verbose) + call brktime (lsttogmt(pos), tm) + call sprintf (Memc[expr], sz_cmd, "\"%04d-%02d-%02d\"") + call pargi (TM_YEAR(tm)) + call pargi (TM_MONTH(tm)) + call pargi (TM_MDAY(tm)) + call ah_evaluate (ast, "$GMD", Memc[expr], eval, verbose) + call sprintf (Memc[expr], sz_cmd, "\"%02d:%02d:%02d\"") + call pargi (TM_HOUR(tm)) + call pargi (TM_MIN(tm)) + call pargi (TM_SEC(tm)) + call ah_evaluate (ast, "$GMT", Memc[expr], eval, verbose) + call sprintf (Memc[expr], sz_cmd, "\"%04d-%02d-%02dT%02d:%02d:%02d\"") + call pargi (TM_YEAR(tm)) + call pargi (TM_MONTH(tm)) + call pargi (TM_MDAY(tm)) + call pargi (TM_HOUR(tm)) + call pargi (TM_MIN(tm)) + call pargi (TM_SEC(tm)) + call ah_evaluate (ast, "$GMDT", Memc[expr], eval, verbose) + + # Open the table file, get the column names, and insert + # fscan in commands. + + Memc[col] = EOS + call clgstr ("table", Memc[table], SZ_FNAME) + if (nowhite (Memc[table], Memc[table], SZ_FNAME) > 0) { + AST_TFD(ast) = open (Memc[table], READ_ONLY, TEXT_FILE) + pos = note (AST_TFD(ast)) + call clgstr ("colnames", Memc[col], SZ_LINE) + i = 0 + ip = 1 + while (ctowrd (Memc[col], ip, Memc[key], SZ_KEY) > 0) { + if (i == 0) + call strcpy ("fscan (\"$", Memc[expr], sz_cmd) + else + call strcat ("\", \"$", Memc[expr], sz_cmd) + call strcat (Memc[key], Memc[expr], sz_cmd) + i = i + 1 + } + if (i > 0) { + call strcat ("\")", Memc[expr], sz_cmd) + Memc[key] = EOS + if (ncmds == 0) { + call malloc (keys, 100, TY_POINTER) + call malloc (exprs, 100, TY_POINTER) + } else if (mod (ncmds, 100) == 0) { + call realloc (keys, ncmds+100, TY_POINTER) + call realloc (exprs, ncmds+100, TY_POINTER) + } + + call salloc (Memi[keys+ncmds], SZ_KEY, TY_CHAR) + call strcpy (Memc[key], Memc[Memi[keys+ncmds]], SZ_KEY) + ip = strlen (Memc[expr]) + call salloc (Memi[exprs+ncmds], ip, TY_CHAR) + call strcpy (Memc[expr], Memc[Memi[exprs+ncmds]], ip) + ncmds = ncmds + 1 + + call ah_evaluate (ast, Memc[key], Memc[expr], eval, verbose) + } + } + + # Read and evaluate commands. + repeat { + if (Memc[prompt] != EOS) { + call printf (Memc[prompt]) + call flush (STDOUT) + } + + # Get next command. Allow for continuation lines. + if (fscan (fdcmd) == EOF) + break + ip = 1 + repeat { + call gargstr (Memc[cmd+ip-1], sz_cmd) + ip = strlen (Memc[cmd]) + if (Memc[cmd+ip-1] != '\\') + break + if (fscan (fdcmd) == EOF) + break + if (ip + SZ_LINE >= sz_cmd) { + sz_cmd = sz_cmd + SZ_LINE + call realloc (cmd, sz_cmd, TY_CHAR) + call realloc (expr, sz_cmd, TY_CHAR) + } + } + + # Eliminate comments, leading/trailing whitespace, and blank lines. + ip = stridxs ("#", Memc[cmd]) + if (ip > 0) + Memc[cmd+ip-1] = EOS + ip = strlen (Memc[cmd]) + while (IS_WHITE(Memc[cmd+ip-1])) + ip = ip - 1 + Memc[cmd+ip] = EOS + ip = 1 + while (IS_WHITE(Memc[cmd+ip-1])) + ip = ip + 1 + call strcpy (Memc[cmd+ip-1], Memc[cmd], sz_cmd) + if (Memc[cmd] == EOS) + next + + # Parse variable. + ip = 1 + if (Memc[cmd+ip-1] == '$') { + ip = ip + 1 + Memc[key] = '$' + i = ctotok (Memc[cmd], ip, Memc[key+1], SZ_KEY) + } else if (Memc[cmd+ip-1] == '@') { + ip = ip + 2 + i = 0 + while (Memc[cmd+ip-1]!=Memc[cmd+1] && Memc[cmd+ip-1]!=EOS) { + Memc[key+i] = Memc[cmd+ip-1] + i = i + 1 + ip = ip + 1 + } + Memc[key+i] = EOS + if (Memc[cmd+ip-1] != Memc[cmd+1]) { + call sprintf (Memc[expr], sz_cmd, + "Syntax error `%s'") + call pargstr (Memc[cmd]) + call error (1, Memc[cmd]) + } + ip = ip + 1 + i = TOK_IDENTIFIER + } else + i = ctotok (Memc[cmd], ip, Memc[key], SZ_KEY) + + switch (i) { + case TOK_IDENTIFIER: + while (IS_WHITE(Memc[cmd+ip-1])) + ip = ip + 1 + if (Memc[cmd+ip-1] == EOS) + ; + else if (Memc[cmd+ip-1] == '=') + ip = ip + 1 + else { + if (oldstyle) { + i = strdic (Memc[key], Memc[expr], sz_cmd, SPECIAL) + if (i > 0 && streq (Memc[key], Memc[expr])) { + ip = 1 + Memc[key] = EOS + } + } else { + ip = 1 + Memc[key] = EOS + } + } + default: + ip = 1 + Memc[key] = EOS + } + + # Parse expression. + while (IS_WHITE(Memc[cmd+ip-1]) || Memc[cmd+ip-1] == '=') + ip = ip + 1 + call strcpy (Memc[cmd+ip-1], Memc[expr], sz_cmd) + + if (streq (Memc[key], "quit")) + break + + # Save command. + if (ncmds == 0) { + call malloc (keys, 100, TY_POINTER) + call malloc (exprs, 100, TY_POINTER) + } else if (mod (ncmds, 100) == 0) { + call realloc (keys, ncmds+100, TY_POINTER) + call realloc (exprs, ncmds+100, TY_POINTER) + } + + call salloc (Memi[keys+ncmds], SZ_KEY, TY_CHAR) + call strcpy (Memc[key], Memc[Memi[keys+ncmds]], SZ_KEY) + ip = strlen (Memc[expr]) + call salloc (Memi[exprs+ncmds], ip, TY_CHAR) + call strcpy (Memc[expr], Memc[Memi[exprs+ncmds]], ip) + + # Evaluate expression. + call ah_evaluate (ast, Memc[key], Memc[expr], eval, verbose) + + ncmds = ncmds + 1 + } + call imunmap (AST_IM(ast)) + call close (fdcmd) + + # Repeat commands for other images. + if (ncmds > 0 && nim > 1) { + while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) { + if (AST_TFD(ast) != NULL) { + if (pos == note (AST_TFD(ast))) + break + if (fstati (AST_TFD(ast), F_EOF) == YES) + call error (1, "Premature end-of-file in table") + } + + iferr (AST_IM(ast) = immap (Memc[image], acmode, 0)) { + call erract (EA_WARN) + next + } + + if (verbose) { + call printf ("%s:\n") + call pargstr (Memc[image]) + } + + eval = TRUE + call sprintf (Memc[expr], sz_cmd, "\"%s\"") + call pargstr (Memc[image]) + call ah_evaluate (ast, "$I", Memc[expr], eval, verbose) + + do i = 1, ncmds + call ah_evaluate (ast, Memc[Memi[keys+i-1]], + Memc[Memi[exprs+i-1]], eval, verbose) + + call imunmap (AST_IM(ast)) + } + } + + if (AST_TFD(ast) != NULL) + call close (AST_TFD(ast)) + if (AST_STP(ast) != NULL) + call stclose (AST_STP(ast)) + call mfree (cmd, TY_CHAR) + call mfree (expr, TY_CHAR) + call sfree (sp) +end + + +# AH_EVALUATE -- Evaluate the value of the named key and add it to symbol table. + +procedure ah_evaluate (ast, key, expr, eval, verbose) + +pointer ast #I Data structure +char key[ARB] #I name of key to be edited +char expr[ARB] #I value expression +bool eval #U Conditional flag +bool verbose #I verbose output? + +bool streq() +pointer sp, newval, oldval, o, im, sym, evvexpr(), stfind(), stenter() +int locpr(), strncmp() +extern ah_getop(), ast_func() +errchk evvexpr + +begin + call smark (sp) + + # Check conditional evaluation. + if (streq (key, "endif")) { + eval = TRUE + return + } else if (streq (key, "else")) { + eval = (!eval) + return + } + if (!eval) + return + + # Evaluate the expression. + o = NULL + if (expr[1] != EOS) + o = evvexpr (expr, locpr (ah_getop), ast, locpr (ast_func), ast, 0) + + # Set conditional evalution. + if (key[1] == EOS) { + if (strncmp (expr, "if ", 3) == 0 || strncmp (expr, "if(", 3) == 0) + eval = (O_VALI(o) != 0) + + } else if (o != NULL) { + # Print the verbose output. + if (verbose) { + call salloc (oldval, SZ_LINE, TY_CHAR) + call salloc (newval, SZ_LINE, TY_CHAR) + + switch (O_TYPE(o)) { + case TY_BOOL: + call sprintf (Memc[newval], SZ_LINE, "%b") + call pargi (O_VALI(o)) + case TY_CHAR: + call sprintf (Memc[newval], SZ_LINE, "%s") + call pargstr (O_VALC(o)) + case TY_INT: + call sprintf (Memc[newval], SZ_LINE, "%d") + call pargi (O_VALI(o)) + case TY_REAL: + call sprintf (Memc[newval], SZ_LINE, "%g") + call pargr (O_VALR(o)) + case TY_DOUBLE: + call sprintf (Memc[newval], SZ_LINE, "%g") + call pargd (O_VALD(o)) + } + + if (key[1] == '$') { + call printf (" %s = %s\n") + call pargstr (key) + call pargstr (Memc[newval]) + } else { + iferr (call imgstr (AST_IM(ast), key, Memc[oldval], + SZ_LINE)) { + call printf (" %s = %s\n") + call pargstr (key) + call pargstr (Memc[newval]) + } else { + call printf (" %s = %s -> %s\n") + call pargstr (key) + call pargstr (Memc[oldval]) + call pargstr (Memc[newval]) + } + } + } + + if (key[1] == '$') { + sym = stfind (AST_STP(ast), key) + if (sym == NULL) + sym = stenter (AST_STP(ast), key, SZ_LINE) + Memi[sym] = O_TYPE(o) + switch (O_TYPE(o)) { + case TY_BOOL: + Memi[sym+2] = O_VALI(o) + case TY_CHAR: + call strcpy (O_VALC(o), Memc[P2C(sym+2)], SZ_LINE) + case TY_INT: + Memi[sym+2] = O_VALI(o) + case TY_REAL: + Memd[P2D(sym+2)] = O_VALR(o) + case TY_DOUBLE: + Memd[P2D(sym+2)] = O_VALD(o) + } + } else if (key[1] != EOS) { + im = AST_IM(ast) + iferr (call imdelf (im, key)) + ; + switch (O_TYPE(o)) { + case TY_BOOL: + call imaddb (im, key, (O_VALI(o) == YES)) + case TY_CHAR: + call imastr (im, key, O_VALC(o)) + case TY_INT: + call imaddi (im, key, O_VALI(o)) + case TY_REAL: + call imaddr (im, key, O_VALR(o)) + case TY_DOUBLE: + call imaddd (im, key, O_VALD(o)) + } + } + } else if (key[1] != '$') { + im = AST_IM(ast) + + # Print the verbose output. + if (verbose) { + call salloc (oldval, SZ_LINE, TY_CHAR) + ifnoerr (call imgstr (im, key, Memc[oldval], SZ_LINE)) { + call printf (" %s = %s -> DELETED\n") + call pargstr (key) + call pargstr (Memc[oldval]) + } + } + + iferr (call imdelf (im, key)) + ; + } + + call mfree (o, TY_STRUCT) + call sfree (sp) +end + + +# AH_GETOP -- Satisfy an operand request from EVEXPR. In this context, +# operand names refer to image keywords or entries in the symbol table. + +procedure ah_getop (ast, operand, o) + +pointer ast #I Data structure +char operand[ARB] #I name of operand to be returned +pointer o #O pointer to output operand + +int ip, type, nchars +pointer sym, im, cp +int lexnum(), ctoi(), ctod(), imaccf(), imgeti(), imgftype() +double imgetd() +pointer stfind() + +begin + # Symbol table values. + if (operand[1] == '$') { + sym = stfind (AST_STP(ast), operand) + if (sym == NULL) + call xvv_error1 ("variable `%s' not found", operand[1]) + + switch (Memi[sym]) { + case TY_BOOL, TY_SHORT, TY_INT, TY_LONG: + call xvv_initop (o, 0, TY_INT) + O_VALI(o) = Memi[sym+2] + + case TY_REAL, TY_DOUBLE, TY_COMPLEX: + call xvv_initop (o, 0, TY_DOUBLE) + O_VALD(o) = Memd[P2D(sym+2)] + + default: + call xvv_initop (o, SZ_LINE, TY_CHAR) + call strcpy (Memc[P2C(sym+2)], O_VALC(o), SZ_LINE) + } + + # Expression values. + } else { + im = AST_IM(ast) + if (imaccf (im, operand) == NO) + call xvv_error1 ("image keyword `%s' not found", operand[1]) + + switch (imgftype (im, operand)) { + case TY_BOOL, TY_SHORT, TY_INT, TY_LONG: + call xvv_initop (o, 0, TY_INT) + O_VALI(o) = imgeti (im, operand) + + case TY_REAL, TY_DOUBLE, TY_COMPLEX: + call xvv_initop (o, 0, TY_DOUBLE) + O_VALD(o) = imgetd (im, operand) + + default: + call malloc (cp, SZ_LINE, TY_CHAR) + call imgstr (im, operand, Memc[cp], SZ_LINE) + + ip = 1 + type = lexnum (Memc[cp], ip, nchars) + if (Memc[cp+nchars+ip-1] != EOS) + type = LEX_NONNUM + + switch (type) { + case LEX_OCTAL, LEX_DECIMAL, LEX_HEX: + call xvv_initop (o, 0, TY_INT) + ip = 1 + nchars = ctoi (Memc[cp], ip, O_VALI(o)) + case LEX_REAL: + call xvv_initop (o, 0, TY_DOUBLE) + ip = 1 + nchars = ctod (Memc[cp], ip, O_VALD(o)) + case LEX_NONNUM: + call xvv_initop (o, SZ_LINE, TY_CHAR) + call strcpy (Memc[cp], O_VALC(o), SZ_LINE) + } + + call mfree (cp, TY_CHAR) + } + } +end |