static void getpw_namekeepalive(int keep, int interval) { int *table; union { nsc_data_t ping; char space[sizeof (nsc_data_t) + NSCDMAXNAMELEN]; } u; int i; if (!keep) return; table = maken(keep); mutex_lock(&passwd_lock); operate_hash(nam_hash, do_findnams, (char *)table); mutex_unlock(&passwd_lock); for (i = 1; i <= keep; i++) { char *tmp; u.ping.nsc_call.nsc_callnumber = GETPWNAM; if ((tmp = (char *)table[keep + 1 + i]) == (char *)-1) continue; /* unused slot in table */ strcpy(u.ping.nsc_call.nsc_u.name, tmp); launch_update(&u.ping.nsc_call); sleep(interval); } for (i = 1; i <= keep; i++) { char *tmp; if ((tmp = (char *)table[keep + 1 + i]) != (char *)-1) free(tmp); } free(table); }
static void getpw_uidkeepalive(int keep, int interval) { int *table; nsc_data_t ping; int i; if (!keep) return; table = maken(keep); mutex_lock(&passwd_lock); operate_hash(uid_hash, do_finduids, (char *)table); mutex_unlock(&passwd_lock); for (i = 1; i <= keep; i++) { ping.nsc_call.nsc_callnumber = GETPWUID; if ((ping.nsc_call.nsc_u.uid = table[keep + 1 + i]) == -1) continue; /* unused slot in table */ launch_update(&ping.nsc_call); sleep(interval); } free(table); }
int ws_inv_cmod5(double sigma0, double phi0, double theta0, double *wnd1, double *wnd2, double min_ws, double max_ws, int npts, double hh) { // ws_cmod5 will return a 2-element array where the first element is the sigma0 // that you'd get at min_ws, and the second element is the sigma0 that you get // at max_ws; // (phi0 is phi_diff, the diff between wind_dir and r_look, and theta0 is incidence angle) // Note that the 0.0 (last parameter) is r_look according to ws_cmod5, but the ws_cmod5 function // doesn't make use of it ...or more accurately, it's already built into the phi0 value. g_assert(max_ws > min_ws); g_assert(npts > 0); double *wd; int i; // Make an npts-element array of windspeeds that range from min_ws to max_ws linearly wd = maken(min_ws, max_ws, npts); g_assert(wd != NULL); // Calculate an npts-element array of normalized radar cross section (NRCS) using // the CMOD5 algorithm double *sg0 = ws_cmod5(wd, npts, phi0, theta0, 0.0); // Returned sg0[] has npts elements in it g_assert(sg0 != NULL); // See lines 118-123 in ws_inv_cmod5.pro // NOTE: The CMOD5 and CMOD4 algorithms need an adjustment when the polarization // is HH (since the original algorithms were developed for VV polarization only) // hh == -3 when polarization is VV, hh == 0.6 when polarization is HH // FIXME: Add cases for hh eq to -1 and -2 double rr = (hh > 0.0) ? ws_pol_ratio(theta0, hh) : 1.0; sigma0 = (hh != -3) ? sigma0 / rr : sigma0; // HH adjustment or not // If sigma0 is lower than what you'd get at minimum windspeed, then set the windspeed to // the minimum and return. (Line 129) double min_nrcs = arr_min(sg0, npts); // Min should be sg0[0], but make sure... if (sigma0 < min_nrcs) { *wnd1 = wd[0]; *wnd2 = WND1_IS_MINIMUM_WIND; FREE(wd); FREE(sg0); return 0; } // Create sign of differences array int ct=0; double *s = (double *)MALLOC(sizeof(double) * npts); for (i=0; i<npts; i++) { s[i] = SIGN(sg0[i] - sigma0); ct += s[i] == 0 ? 1 : 0; s[i] = (ct > 0 && s[i] == 0) ? 1.0 : s[i]; } // Count the sign changes ct = 0; int ww = -1; // Where first sign change occurs int ww2 = -1; // Where second sign change occurs for (i=1; i<npts; i++) { ct += (s[i] != s[i-1]) ? 1 : 0; ww = (ct > 0 && ww < 0) ? i : ww; ww2 = (ct > 0 && ww > 0 && ww2 < 0) ? i : ww2; } // Calculate wind for the 3 cases (no sign changes, one sign change, two sign changes, and other) switch(ct) { case 0: { // No sign changes means sigma0 > max(sg0[]) int nn = npts; double max_sg0 = arr_max(sg0, npts); int idx_first_max = -1; int *w = (int *)CALLOC(nn, sizeof(int)); int wx = 0; for (i=0; i<npts; i++) { if (sg0[i] >= max_sg0) { idx_first_max = (idx_first_max < 0) ? i : idx_first_max; w[wx++] = i; // Collect indices of max's } } if (idx_first_max == nn - 1) { // Last element was the largest element, so send back max wind *wnd1 = wd[nn-1]; *wnd2 = WND_FROM_MAX_SIGMA0; } else { int ix1 = (w[0] - 1 >= 0) ? w[0] - 1 : 0; int ix2 = w[0]; int ix3 = w[0] + 1; double fit1; double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1); *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sg0[ix2])))/2/f1[2]; *wnd2 = WND_FROM_MAX_SIGMA0; } FREE(w); } break; case 1: { // Single solution int ix1 = ww; int ix2 = (ww+1) > npts - 1 ? npts - 1 : ww+1; int ix3 = (ww+2) > npts - 1 ? npts - 1 : ww+2; double fit1; double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1); *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sigma0)))/2/f1[2]; *wnd2 = WND1_IS_ONLY_SOLUTION; } break; case 2: { // Two solutions (usually lowest answer of the two is best answer) int ix1 = ww; int ix2 = (ww+1) > npts - 1 ? npts - 1 : ww+1; int ix3 = (ww+2) > npts - 1 ? npts - 1 : ww+2; int ix4 = ww2; int ix5 = (ww2+1) > npts - 1 ? npts - 1 : ww2+1; int ix6 = (ww2+2) > npts - 1 ? npts - 1 : ww2+2; double fit1, fit2; double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1); double *f2 = poly_fit(wd, sg0, ix4, ix5, ix6, 2, &fit2); *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sigma0)))/2/f1[2]; *wnd2 = (f2[1]+sqrt(f2[1]*f2[1]-4.0*f2[2]*(f2[0]-sigma0)))/2/f2[2]; } break; default: *wnd1 = WND_FROM_MAX_SIGMA0; *wnd2 = WND_FROM_MAX_SIGMA0; break; } FREE(s); FREE(wd); FREE(sg0); return 0; }
obj parse_format_string( obj str ) { obj entry, substr, prev, first, next; const char *begin, *s, *limit; int sharp_flag, star_flag, negative_flag; int pre_dot_lead_zero, pre_dot_num; int post_dot_digits, post_dot_num; obj at_flag, braced; prev = first = cons( FALSE_OBJ, NIL_OBJ ); begin = s = string_text(str); limit = begin + string_length(str); while (s < limit) { if (s[0] == '~' && (s+1 < limit)) { if (begin != s) { /* flush the chars we've seen so far... */ substr = bvec_alloc( s - begin + 1, string_class ); memcpy( PTR_TO_DATAPTR(substr), (void*)begin, s - begin ); next = cons( substr, NIL_OBJ ); gvec_write_fresh_ptr( prev, SLOT(1), next ); prev = next; } begin = ++s; pre_dot_lead_zero = 0; post_dot_digits = -1; pre_dot_num = -1; post_dot_num = -1; sharp_flag = 0; star_flag = 0; at_flag = FALSE_OBJ; braced = FALSE_OBJ; another: switch (*s) { case '#': sharp_flag = 1; s++; goto another; case '*': star_flag = 1; s++; goto another; case '@': at_flag = TRUE_OBJ; s++; goto another; case '{': { const char *sb = s; unsigned n; while ((s < limit) && (*s != '}')) s++; n = s - sb - 1; braced = bvec_alloc( n+1, string_class ); memcpy( string_text( braced ), sb+1, n ); if (s < limit) s++; /* skip the brace itself */ goto another; } } if (*s == '-') { s++; negative_flag = 1; } else negative_flag = 0; if (isdigit(*(unsigned char *)s)) { pre_dot_num = 0; if (*s == '0') { s++; pre_dot_lead_zero = 1; } while (isdigit(*(unsigned char *)s)) { pre_dot_num = (pre_dot_num * 10) + *s++ - '0'; } } if (*s == '.') { s++; post_dot_num = 0; post_dot_digits = 0; while (isdigit(*(unsigned char *)s)) { post_dot_digits++; post_dot_num = (post_dot_num * 10) + *s++ - '0'; } } if (begin == s) { entry = MAKE_ASCII_CHAR( *s ); } else { entry = maken( vector_class, 10, MAKE_ASCII_CHAR( *s ), sharp_flag ? TRUE_OBJ : FALSE_OBJ, star_flag ? TRUE_OBJ : FALSE_OBJ, at_flag, negative_flag ? TRUE_OBJ : FALSE_OBJ, pre_dot_lead_zero ? TRUE_OBJ : FALSE_OBJ, (pre_dot_num < 0) ? FALSE_OBJ : int2fx(pre_dot_num), (post_dot_digits < 0) ? FALSE_OBJ : int2fx(post_dot_digits), (post_dot_num < 0) ? FALSE_OBJ : int2fx(post_dot_num), braced ); } next = cons( entry, NIL_OBJ ); gvec_write_fresh_ptr( prev, SLOT(1), next ); prev = next; begin = ++s; } else s++; } if (begin != s) { substr = bvec_alloc( s - begin + 1, string_class ); memcpy( PTR_TO_DATAPTR(substr), (void*)begin, s - begin ); next = cons( substr, NIL_OBJ ); gvec_write_fresh_ptr( prev, SLOT(1), next ); } return pair_cdr(first); }