IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 27, 2019, 12:09:13 PM (7 years ago)
Author:
eugene
Message:

enable multicolumn output fits tables; add bitshifts using <~ and ~>

Location:
trunk/Ohana
Files:
6 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Ohana

  • trunk/Ohana/src/opihi/lib.data/SplineOps.c

    r41162 r41176  
    181181
    182182  // NOTE: if we want to compress the output table, use native byte order here (last element)
    183   gfits_set_bintable_column_reformat (&theader, &ftable, "X_KNOT", "double", myspline->xk, myspline->Nknots, FALSE);
    184   gfits_set_bintable_column_reformat (&theader, &ftable, "Y_KNOT", "double", myspline->yk, myspline->Nknots, FALSE);
    185   gfits_set_bintable_column_reformat (&theader, &ftable, "DY2_DX", "double", myspline->y2, myspline->Nknots, FALSE);
     183  gfits_set_bintable_column_reformat (&theader, &ftable, "X_KNOT", "double", myspline->xk, myspline->Nknots, 0, FALSE);
     184  gfits_set_bintable_column_reformat (&theader, &ftable, "Y_KNOT", "double", myspline->yk, myspline->Nknots, 0, FALSE);
     185  gfits_set_bintable_column_reformat (&theader, &ftable, "DY2_DX", "double", myspline->y2, myspline->Nknots, 0, FALSE);
    186186
    187187  if (!append) {
  • trunk/Ohana/src/opihi/lib.shell/VectorIO.c

    r41161 r41176  
    77  int j;
    88
    9   char *tformat = NULL;
    10 
    119  Header *theader = ftable->header;
    1210  gfits_create_table_header (theader, "BINTABLE", extname);
    1311
    14   ALLOCATE (tformat, char, 2*Nvec);
     12  // allocate an array of strings to represent the format for each output field
     13  // formats include single column formats (BIJKDE) and multi-column formats (e.g., 2I)
     14  // we will have no more than Nvec fields (but we can have fewer)
     15  int Nfield = 0;
     16  ALLOCATE_PTR (tformat, char *, Nvec);
     17  ALLOCATE_PTR (Nelement, int, Nvec);
     18
    1519  if (format) {
    16     // the bintable format string can only define the byte-width of each field.  valid output columns are currently:
     20    // the bintable format string can defines the byte-width of each field and number of elements (columns per field).
     21    // valid output columns are currently:
    1722    // B (char), I (16 bit short), J (32 bit int), E (32 bit float), D (64 bit double).
    18     // the format string is just the sequence of types, eg: LIIJEED
    19     // validate the format string
     23    // the format string is just the sequence of types, eg: LIIJEED.
     24    // it may have spaces or integer element counts:
     25    // "2D 4I EEJ"
     26
     27    // *** validate the format string
     28
     29    // as I parse each elements, if it is a digit, I need parse that value
     30
    2031    char *ptr = format;
    21     for (j = 0; j < Nvec; j++) {
     32    for (j = 0; j < Nvec; ) {
    2233      while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
    2334      if (*ptr == 0) {
     
    2536        goto escape;
    2637      }
     38
     39      // is there a leading integer?
     40      char *endptr;
     41      Nelement[Nfield] = strtol (ptr, &endptr, 10);
     42      if (endptr == ptr) {
     43        Nelement[Nfield] = 1;
     44      }
     45      ptr = endptr; // this should now point at the letter that is the format type
    2746      if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E')) {
    2847        gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr);
    2948        goto escape;
    3049      }
    31       tformat[2*j + 0] = *ptr;
    32       tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
     50
     51      int Nchar = snprintf (tformat[Nfield], 0, "%d%c", Nelement[Nfield], *ptr);
     52      ALLOCATE (tformat[Nfield], char, Nchar + 1);
     53      int Nout = snprintf (tformat[Nfield], Nchar + 1, "%d%c", Nelement[Nfield], *ptr);
     54      myAssert (Nout <= Nchar, "oops");
     55
     56      // tformat[2*j + 0] = *ptr;
     57      // tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
     58
     59      j += Nelement[Nfield]; // advance past
     60      if (j > Nvec) {
     61        gprint (GP_ERR, "error in binary table format %s (too few vectors for listed field)\n", format);
     62        goto escape;
     63      }
     64
    3365      ptr ++;
     66      Nfield ++;
    3467    }
    3568    while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
     
    4174    for (j = 0; j < Nvec; j++) {
    4275      // if the format is not defined, just use the native byte-widths
    43       tformat[2*j + 0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'K'; // this depends on opihi_int == int64_t for Int
    44       tformat[2*j + 1] = 0;
    45     }
     76      ALLOCATE (tformat[j], char, 2);
     77      tformat[j][0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'K'; // this depends on opihi_int == int64_t for Int
     78      tformat[j][1] = 0;
     79      Nelement[j] = 1;
     80    }
     81    Nfield = Nvec;
    4682  }
    4783
     
    4985  // output table (because the data goes to the named column below).  need to enforce
    5086  // this somehow
    51   for (j = 0; j < Nvec; j++) {
    52     gfits_define_bintable_column (theader, &tformat[2*j], vec[j][0].name, NULL, NULL, 1.0, 0.0);
     87  int ivec = 0;
     88  for (j = 0; j < Nfield; j++) {
     89    // XX need to loop over fields, and skip the additional vectors that are part of a field
     90    // this call supported multiple columns per named field
     91    gfits_define_bintable_column (theader, tformat[j], vec[ivec][0].name, NULL, NULL, 1.0, 0.0);
     92    ivec += Nelement[j];
     93  }
     94
     95  // need to free the array
     96  for (j = 0; j < Nfield; j++) {
     97    free (tformat[j]);
    5398  }
    5499  free (tformat);
     
    57102  gfits_create_table (theader, ftable);
    58103
     104  // I need to add each vector in order, but I need to
     105  // track which field it corresponds to.
     106
    59107  // add the vectors to the output array
    60   for (j = 0; j < Nvec; j++) {
    61     if (vec[j][0].type == OPIHI_FLT) {
    62       gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "double",  vec[j][0].elements.Flt, vec[j][0].Nelements, nativeOrder);
    63     } else {
    64 //    gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "int",     vec[j][0].elements.Int, vec[j][0].Nelements, nativeOrder);
    65       gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "int64_t", vec[j][0].elements.Int, vec[j][0].Nelements, nativeOrder);
     108  for (ivec = 0, j = 0; j < Nfield; j++) {
     109    // the first vector provides the name for the field
     110    char *fieldname = vec[ivec][0].name;
     111    for (int k = 0; k < Nelement[j]; k++, ivec++) {
     112      Vector *thisvec = vec[ivec];
     113      if (thisvec->type == OPIHI_FLT) {
     114        gfits_set_bintable_column_reformat (theader, ftable, fieldname, "double",  thisvec->elements.Flt, thisvec->Nelements, k, nativeOrder);
     115      } else {
     116        gfits_set_bintable_column_reformat (theader, ftable, fieldname, "int64_t", thisvec->elements.Int, thisvec->Nelements, k, nativeOrder);
     117      }
    66118    }
    67119  }
  • trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c

    r40291 r41176  
    7878    if (!strcmp (argv[i], "atan2"))  { type = ST_BINARY; strcpy (argv[i], "a"); goto gotit; }
    7979    if (!strcmp (argv[i], "datan2")) { type = ST_BINARY; strcpy (argv[i], "d"); goto gotit; }
     80
     81    if (!strcmp (argv[i], "<~"))     { type = ST_BINARY; strcpy (argv[i], "l"); goto gotit; }
     82    if (!strcmp (argv[i], "~>"))     { type = ST_BINARY; strcpy (argv[i], "r"); goto gotit; }
     83
    8084    if (!strcmp (argv[i], ","))      { type = ST_COMMA; goto gotit; }
    8185
     
    99103    if (!strcmp (argv[i], ">>"))     { type = ST_LOGIC; strcpy (argv[i], "U"); goto gotit; }
    100104    if (!strcmp (argv[i], "<<"))     { type = ST_LOGIC; strcpy (argv[i], "D"); goto gotit; }
     105
     106    /* XXX I would like to change the syntax to allow << and >> to mean bitshifts
     107       but that means breaking these older values which means MIN and MAX */
     108    // for now, use <- and -> to mean bitshift
    101109
    102110    if (!strcmp (argv[i], "&&"))     { type = ST_AND; strcpy (argv[i], "A"); goto gotit; }
  • trunk/Ohana/src/opihi/lib.shell/parse.c

    r40574 r41176  
    6666        /* dvomath returns a new string, or NULL, with the result of the expression */
    6767        val = dvomath (1, &V1, &size, 0);
    68         if (val == NULL) goto error;
     68        if (val == NULL) { print_error (); goto error; }
    6969        fval += atof(val);
    7070        // save the result
     
    8888        /* dvomath returns a new string, or NULL, with the result of the expression */
    8989        val = dvomath (1, &V1, &size, 0);
    90         if (val == NULL) goto error;
     90        if (val == NULL) { print_error (); goto error; }
    9191        fval -= atof(val);
    9292        // save the result
  • trunk/Ohana/src/opihi/lib.shell/stack_math.c

    r40331 r41176  
    3434    case '?': SSS_FUNC(M1 ? M2: M3);
    3535    default:
    36       snprintf (line, 512, "error: op %c not defined!", op[0]);
     36      snprintf (line, 512, "error: op %c not defined as scalar trinary op!", op[0]);
    3737      push_error (line);
    3838      return (FALSE);
     
    162162    case '?': VVV_FUNC(*M1 ? *M2: *M3);
    163163    default:
    164       snprintf (line, 512, "error: op %c not defined!", op[0]);
     164      snprintf (line, 512, "error: op %c not defined as vector trinary op!", op[0]);
    165165      push_error (line);
    166166      return (FALSE);
     
    227227    case '?': MMM_FUNC(*M1 ? *M2: *M3);
    228228    default:
    229       snprintf (line, 512, "error: op %c not defined!", op[0]);
     229      snprintf (line, 512, "error: op %c not defined as matrix trinary op!", op[0]);
    230230      push_error (line);
    231231      return (FALSE);
     
    357357    case 'A': VV_FUNC(ST_SCALAR_INT, (*M1 && *M2) ? 1 : 0);
    358358    case 'O': VV_FUNC(ST_SCALAR_INT, (*M1 || *M2) ? 1 : 0);
     359
     360    // for the bitshift operators, we have to treat the INT and FLT values differently
     361    // this makes the operator incompatible with the macros used above
     362    case 'l': {
     363      CopyVector (OUT[0].vector, V1[0].vector);
     364      if ((V1->vector->type == OPIHI_FLT) || (V2->vector->type == OPIHI_FLT)) {
     365        // bitshift is not valid with float valuess
     366        for (i = 0; i < Nx; i++) {
     367          OUT[0].vector[0].elements.Flt[i] = NAN;
     368        }
     369        break;
     370      }
     371      // I could just do this for all types and bitshift regardless...
     372      opihi_int *M1  =  V1[0].vector[0].elements.Int;
     373      opihi_int *M2  =  V2[0].vector[0].elements.Int;
     374      opihi_int *out = OUT[0].vector[0].elements.Int;
     375      for (i = 0; i < Nx; i++, out++, M1++, M2++) {
     376        *out = *M1 << *M2;
     377      }
     378      break;
     379    }
     380
     381    case 'r': {
     382      CopyVector (OUT[0].vector, V1[0].vector);
     383      if ((V1->vector->type == OPIHI_FLT) || (V2->vector->type == OPIHI_FLT)) {
     384        // bitshift is not valid with float valuess
     385        CopyVector (OUT[0].vector, V1[0].vector);
     386        for (i = 0; i < Nx; i++) {
     387          OUT[0].vector[0].elements.Flt[i] = NAN;
     388        }
     389        break;
     390      }
     391      // I could just do this for all types and bitshift regardless...
     392      opihi_int *M1  =  V1[0].vector[0].elements.Int;
     393      opihi_int *M2  =  V2[0].vector[0].elements.Int;
     394      opihi_int *out = OUT[0].vector[0].elements.Int;
     395      for (i = 0; i < Nx; i++, out++, M1++, M2++) {
     396        *out = *M1 >> *M2;
     397      }
     398      break;
     399    }
     400
    359401    default:
    360       snprintf (line, 512, "error: op %c not defined!", op[0]);
     402      snprintf (line, 512, "error: op %c not defined for (vector OP vector)!", op[0]);
    361403      push_error (line);
    362404      return (FALSE);
     
    469511    case 'A': SV_FUNC(ST_SCALAR_INT, (M1 && *M2) ? 1 : 0);
    470512    case 'O': SV_FUNC(ST_SCALAR_INT, (M1 || *M2) ? 1 : 0);
     513
     514    // for the bitshift operators, we have to treat the INT and FLT values differently
     515    // this makes the operator incompatible with the macros used above
     516    case 'l': {
     517      CopyVector (OUT[0].vector, V2[0].vector);
     518      if ((V1->type == ST_SCALAR_FLT) || (V2->vector->type == OPIHI_FLT)) {
     519        // bitshift is not valid with float valuess
     520        for (i = 0; i < Nx; i++) {
     521          OUT[0].vector[0].elements.Flt[i] = NAN;
     522        }
     523        break;
     524      }
     525      opihi_int  M1  =  V1[0].IntValue;                                 \
     526      opihi_int *M2  =  V2[0].vector[0].elements.Int;
     527      opihi_int *out = OUT[0].vector[0].elements.Int;
     528      for (i = 0; i < Nx; i++, out++, M2++) {
     529        *out = M1 << *M2;
     530      }
     531      break;
     532    }
     533
     534    case 'r': {
     535      CopyVector (OUT[0].vector, V2[0].vector);
     536      if ((V1->type == ST_SCALAR_FLT) || (V2->vector->type == OPIHI_FLT)) {
     537        // bitshift is not valid with float valuess
     538        for (i = 0; i < Nx; i++) {
     539          OUT[0].vector[0].elements.Flt[i] = NAN;
     540        }
     541        break;
     542      }
     543      opihi_int  M1  =  V1[0].IntValue;                                 \
     544      opihi_int *M2  =  V2[0].vector[0].elements.Int;
     545      opihi_int *out = OUT[0].vector[0].elements.Int;
     546      for (i = 0; i < Nx; i++, out++, M2++) {
     547        *out = M1 >> *M2;
     548      }
     549      break;
     550    }
     551
    471552    default:
    472       snprintf (line, 512, "error: op %c not defined!", op[0]);
     553      snprintf (line, 512, "error: op %c not defined for (scalar OP vector)!", op[0]);
    473554      push_error (line);
    474555      return (FALSE);
     
    577658    case 'A': VS_FUNC(ST_SCALAR_INT, (*M1 && M2) ? 1 : 0);
    578659    case 'O': VS_FUNC(ST_SCALAR_INT, (*M1 || M2) ? 1 : 0);
     660
     661    case 'l': {
     662      CopyVector (OUT[0].vector, V1[0].vector);
     663      if ((V1->vector->type == OPIHI_FLT) || (V2->type == ST_SCALAR_FLT)) {
     664        // bitshift is not valid with float valuess
     665        for (i = 0; i < Nx; i++) {
     666          OUT[0].vector[0].elements.Flt[i] = NAN;
     667        }
     668        break;
     669      }
     670      opihi_int *M1  =  V1[0].vector[0].elements.Int;
     671      opihi_int  M2  =  V2[0].IntValue;                                 \
     672      opihi_int *out = OUT[0].vector[0].elements.Int;
     673      for (i = 0; i < Nx; i++, out++, M1++) {
     674        *out = *M1 << M2;
     675      }
     676      break;
     677    }
     678
     679    case 'r': {
     680      CopyVector (OUT[0].vector, V1[0].vector);
     681      if ((V1->vector->type == OPIHI_FLT) || (V2->type == ST_SCALAR_FLT)) {
     682        // bitshift is not valid with float valuess
     683        CopyVector (OUT[0].vector, V1[0].vector);
     684        for (i = 0; i < Nx; i++) {
     685          OUT[0].vector[0].elements.Flt[i] = NAN;
     686        }
     687        break;
     688      }
     689      opihi_int *M1  =  V1[0].vector[0].elements.Int;
     690      opihi_int  M2  =  V2[0].IntValue;                                 \
     691      opihi_int *out = OUT[0].vector[0].elements.Int;
     692      for (i = 0; i < Nx; i++, out++, M1++) {
     693        *out = *M1 >> M2;
     694      }
     695      break;
     696    }
     697
    579698    default:
    580       snprintf (line, 512, "error: op %c not defined!", op[0]);
     699      snprintf (line, 512, "error: op %c not defined for (vector OP scalar)!", op[0]);
    581700      push_error (line);
    582701      return (FALSE);
     
    670789    case 'A': MV_FUNC((*M1 && *M2) ? 1 : 0);
    671790    case 'O': MV_FUNC((*M1 || *M2) ? 1 : 0);
     791
    672792    default:
    673       snprintf (line, 512, "error: op %c not defined!", op[0]);
     793      snprintf (line, 512, "error: op %c not defined for (matrix OP vector)!", op[0]);
    674794      push_error (line);
    675795      return (FALSE);
     
    768888    case 'O': VM_FUNC((*M1 || *M2) ? 1 : 0);
    769889    default:
    770       snprintf (line, 512, "error: op %c not defined!", op[0]);
     890      snprintf (line, 512, "error: op %c not defined for (vector OP matrix)!", op[0]);
    771891      push_error (line);
    772892      return (FALSE);
     
    849969    case 'O': MM_FUNC((*M1 || *M2) ? 1 : 0);
    850970    default:
    851       snprintf (line, 512, "error: op %c not defined!", op[0]);
     971      snprintf (line, 512, "error: op %c not defined for (matrix OP matrix)!", op[0]);
    852972      push_error (line);
    853973      return (FALSE);
     
    9351055    case 'O': MS_FUNC((*M1 || M2) ? 1 : 0);
    9361056    default:
    937       snprintf (line, 512, "error: op %c not defined!", op[0]);
     1057      snprintf (line, 512, "error: op %c not defined for (matrix OP scalar)!", op[0]);
    9381058      push_error (line);
    9391059      return (FALSE);
     
    10121132    case 'O': SM_FUNC((M1 || *M2) ? 1 : 0);
    10131133    default:
    1014       snprintf (line, 512, "error: op %c not defined!", op[0]);
     1134      snprintf (line, 512, "error: op %c not defined for (scalar OP matrix)!", op[0]);
    10151135      push_error (line);
    10161136      return (FALSE);
     
    10941214    case 'A': SS_FUNC(ST_SCALAR_INT, (M1 && M2) ? 1 : 0);
    10951215    case 'O': SS_FUNC(ST_SCALAR_INT, (M1 || M2) ? 1 : 0);
     1216
     1217    // for the bitshift operators, we have to treat the INT and FLT values differently
     1218    // this makes the operator incompatible with the macros used above
     1219    case 'l': {
     1220      if ((V1->type == ST_SCALAR_FLT) || (V2->type == ST_SCALAR_FLT)) {
     1221        // bitshift is not valid with float valuess
     1222        OUT[0].type = ST_SCALAR_FLT;
     1223        OUT[0].FltValue = NAN;
     1224        break;
     1225      }
     1226      opihi_int M1 = V1[0].IntValue;
     1227      opihi_int M2 = V2[0].IntValue;
     1228      OUT[0].type = ST_SCALAR_INT;
     1229      OUT[0].IntValue = M1 << M2;
     1230      break;
     1231    }
     1232
     1233    case 'r': {
     1234      if ((V1->type == ST_SCALAR_FLT) || (V2->type == ST_SCALAR_FLT)) {
     1235        // bitshift is not valid with float valuess
     1236        OUT[0].type = ST_SCALAR_FLT;
     1237        OUT[0].FltValue = NAN;
     1238        break;
     1239      }
     1240      opihi_int M1 = V1[0].IntValue;
     1241      opihi_int M2 = V2[0].IntValue;
     1242      OUT[0].type = ST_SCALAR_INT;
     1243      OUT[0].IntValue = M1 >> M2;
     1244      break;
     1245    }
     1246
    10961247    default:
    1097       snprintf (line, 512, "error: op %c not defined!", op[0]);
     1248      snprintf (line, 512, "error: op %c not defined for (scalar OP scalar)!", op[0]);
    10981249      push_error (line);
    10991250      return (FALSE);
     
    11681319int S_unary (StackVar *OUT, StackVar *V1, char *op) {
    11691320
    1170   char line[512]; // this is only used to report an error
    1171  
    11721321# define S_FUNC(OP,FTYPE) {                                             \
    11731322    if (V1->type == ST_SCALAR_FLT) {                                    \
     
    12101359  if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1), ST_SCALAR_FLT);
    12111360  if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1), ST_SCALAR_FLT);
    1212   if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), ST_SCALAR_FLT);
    12131361  if (!strcmp (op, "sin"))    S_FUNC(sin (M1), ST_SCALAR_FLT);
    12141362  if (!strcmp (op, "cos"))    S_FUNC(cos (M1), ST_SCALAR_FLT);
     
    12231371  if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD, ST_SCALAR_FLT);
    12241372  if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD, ST_SCALAR_FLT);
     1373  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), ST_SCALAR_FLT);
    12251374  if (!strcmp (op, "rnd"))    S_FUNC(0.0*M1 + drand48(), ST_SCALAR_FLT);
    12261375  if (!strcmp (op, "drnd"))   S_FUNC(0.0*M1 + drand48(), ST_SCALAR_FLT);
     
    12351384
    12361385  clear_stack (V1);
    1237   snprintf (line, 512, "error: op %s not defined!", op);
     1386
     1387  char line[512]; // this is only used to report an error
     1388  snprintf (line, 512, "error: op %s not defined as unary scalar op!", op);
    12381389  push_error (line);
    12391390  return (FALSE);
    1240 
    12411391}
    12421392
     
    12951445  if (!strcmp (op, "asinh"))  V_FUNC(asinh(*M1), ST_SCALAR_FLT);
    12961446  if (!strcmp (op, "acosh"))  V_FUNC(acosh(*M1), ST_SCALAR_FLT);
    1297   if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), ST_SCALAR_FLT);
    12981447  if (!strcmp (op, "sin"))    V_FUNC(sin(*M1), ST_SCALAR_FLT);
    12991448  if (!strcmp (op, "cos"))    V_FUNC(cos(*M1), ST_SCALAR_FLT);
     
    13081457  if (!strcmp (op, "dacos"))  V_FUNC(acos(*M1)*DEG_RAD, ST_SCALAR_FLT);
    13091458  if (!strcmp (op, "datan"))  V_FUNC(atan(*M1)*DEG_RAD, ST_SCALAR_FLT);
     1459  if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), ST_SCALAR_FLT);
    13101460  if (!strcmp (op, "rnd"))    V_FUNC(drand48(), ST_SCALAR_FLT);
    13111461  if (!strcmp (op, "drnd"))   V_FUNC(drand48(), ST_SCALAR_FLT);
    13121462  if (!strcmp (op, "lrnd"))   V_FUNC(lrand48(), ST_SCALAR_INT);
    13131463  if (!strcmp (op, "mrnd"))   V_FUNC(mrand48(), ST_SCALAR_INT);
    1314   if (!strcmp (op, "ramp"))   V_FUNC(i, ST_SCALAR_INT);
    1315   if (!strcmp (op, "zero"))   V_FUNC(0, ST_SCALAR_INT);
    13161464  if (!strcmp (op, "not"))    V_FUNC(!(*M1), ST_SCALAR_INT);
    13171465  if (!strcmp (op, "--"))     V_FUNC(-1*(*M1), ST_SCALAR_INT); // NOTE: opihi_int is signed
    13181466  if (!strcmp (op, "isinf"))  V_FUNC(!finite(*M1), ST_SCALAR_FLT);
    13191467  if (!strcmp (op, "isnan"))  V_FUNC(isnan((opihi_flt)(*M1)), ST_SCALAR_FLT);
     1468  if (!strcmp (op, "ramp"))   V_FUNC(i, ST_SCALAR_INT);
    13201469  if (!strcmp (op, "xramp"))  V_FUNC(i, ST_SCALAR_INT);
    13211470  if (!strcmp (op, "yramp"))  V_FUNC(0, ST_SCALAR_INT);
    13221471  if (!strcmp (op, "zramp"))  V_FUNC(0, ST_SCALAR_INT);
     1472  if (!strcmp (op, "zero"))   V_FUNC(0, ST_SCALAR_INT);
    13231473  /* xramp, yramp, zramp above only make sense for matrices. for vectors, xramp = ramp, yramp = zero */
    13241474
    13251475# undef V_FUNC
    13261476
    1327 escape:
    1328 
     1477  // free the temp vector if needed
    13291478  if (V1[0].type == ST_VECTOR_TMP) {
    13301479    free (V1[0].vector[0].elements.Ptr);
     
    13341483
    13351484  clear_stack (V1);
     1485
     1486  char line[512]; // this is only used to report an error
     1487  snprintf (line, 512, "error: op %s not defined as unary vector op!", op);
     1488  push_error (line);
     1489  return (FALSE);
     1490
     1491escape:
     1492
     1493  if (V1[0].type == ST_VECTOR_TMP) {
     1494    free (V1[0].vector[0].elements.Ptr);
     1495    free (V1[0].vector);
     1496    V1[0].vector = NULL;
     1497  } 
     1498
     1499  clear_stack (V1);
    13361500  return (TRUE);
    13371501
    13381502}
    13391503
    1340 # define M_FUNC(OP) { for (i = 0; i < Npix; i++, out++, M1++) { *out = (OP); }}
     1504# define M_FUNC(OP) { for (i = 0; i < Npix; i++, out++, M1++) { *out = (OP); } goto escape; }
    13411505
    13421506int M_unary (StackVar *OUT, StackVar *V1, char *op) {
     
    13601524// if (!strcmp (op, "rint"))  { for (i = 0; i < Npix; i++, out++, M1++) { *out = nearbyint (*M1); }}
    13611525 
    1362   if (!strcmp (op, "="))     { }
     1526  if (!strcmp (op, "="))      { goto escape; }
    13631527  if (!strcmp (op, "abs"))    M_FUNC(fabs(*M1));
    13641528  if (!strcmp (op, "int"))    M_FUNC((opihi_flt)(long long)(*M1));
     
    13751539  if (!strcmp (op, "asinh"))  M_FUNC(asinh(*M1));
    13761540  if (!strcmp (op, "acosh"))  M_FUNC(acosh(*M1));
    1377   if (!strcmp (op, "lgamma")) M_FUNC(lgamma(*M1));
    13781541  if (!strcmp (op, "sin"))    M_FUNC(sin(*M1));
    13791542  if (!strcmp (op, "cos"))    M_FUNC(cos(*M1));
     
    13881551  if (!strcmp (op, "dacos"))  M_FUNC(acos(*M1)*DEG_RAD);
    13891552  if (!strcmp (op, "datan"))  M_FUNC(atan(*M1)*DEG_RAD);
    1390   if (!strcmp (op, "not"))    M_FUNC(!(*M1));
    1391   if (!strcmp (op, "--"))     M_FUNC(-(*M1));
     1553  if (!strcmp (op, "lgamma")) M_FUNC(lgamma(*M1));
    13921554  if (!strcmp (op, "rnd"))    M_FUNC(drand48());
    13931555  if (!strcmp (op, "drnd"))   M_FUNC(drand48());
    13941556  if (!strcmp (op, "lrnd"))   M_FUNC(lrand48());
    13951557  if (!strcmp (op, "mrnd"))   M_FUNC(mrand48());
     1558  if (!strcmp (op, "not"))    M_FUNC(!(*M1));
     1559  if (!strcmp (op, "--"))     M_FUNC(-(*M1));
    13961560  if (!strcmp (op, "ramp"))   M_FUNC(i);
    1397   if (!strcmp (op, "zero"))   M_FUNC(0);
    13981561  if (!strcmp (op, "isinf"))  M_FUNC(!finite(*M1));
    13991562  if (!strcmp (op, "isnan"))  M_FUNC(isnan(*M1));
     1563  if (!strcmp (op, "zero"))   M_FUNC(0);
    14001564
    14011565  /* xrm and yrm only make sense for 2D matrices. see special meaning for vectors */
     
    14111575      }
    14121576    }
     1577    goto escape;
    14131578  }
    14141579  if (!strcmp (op, "yramp")) {
     
    14231588      }
    14241589    }
     1590    goto escape;
    14251591  }
    14261592  if (!strcmp (op, "zramp")) {
     
    14351601      }
    14361602    }
    1437   }
    1438  
     1603    goto escape;
     1604  }
     1605 
     1606  if (V1[0].type == ST_MATRIX_TMP) {
     1607    free (V1[0].buffer[0].header.buffer);
     1608    free (V1[0].buffer[0].matrix.buffer);
     1609    free (V1[0].buffer);
     1610  }
     1611
     1612  clear_stack (V1);
     1613
     1614  char line[512]; // this is only used to report an error
     1615  snprintf (line, 512, "error: op %s not defined as unary matrix op!", op);
     1616  push_error (line);
     1617  return (FALSE);
     1618
     1619 escape:
     1620
    14391621  if (V1[0].type == ST_MATRIX_TMP) {
    14401622    free (V1[0].buffer[0].header.buffer);
Note: See TracChangeset for help on using the changeset viewer.