int main(int argc, char **argv) { #ifdef _OPENMP printf("ERKALE - EMD from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads()); #else printf("ERKALE - EMD from Hel, serial version.\n"); #endif print_copyright(); print_license(); #ifdef SVNRELEASE printf("At svn revision %s.\n\n",SVNREVISION); #endif print_hostname(); if(argc!=1 && argc!=2) { printf("Usage: $ %s (runfile)\n",argv[0]); return 0; } Timer t; // Parse settings Settings set; set.add_string("LoadChk","Checkpoint file to load density from","erkale.chk"); set.add_bool("DoEMD", "Perform calculation of isotropic EMD (moments of EMD, Compton profile)", true); set.add_double("EMDTol", "Tolerance for the numerical integration of the radial EMD",1e-8); set.add_string("EMDlm", "Which projection of the radial EMD to compute",""); set.add_bool("EMDAdapt", "Use adaptive grid to compute EMD?", true); set.add_string("EMDCube", "Calculate EMD on a cube? e.g. -10:.3:10 -5:.2:4 -2:.1:3", ""); set.add_string("EMDOrbitals", "Compute EMD of given orbitals, e.g. 1,2,4:6",""); set.add_string("Similarity", "Compute similarity measure to checkpoint",""); set.add_string("SimilarityGrid", "Grid to use for computing similarity integrals","500 77"); set.add_bool("SimilarityLM", "Seminumerical computation of similarity integrals?", false); set.add_int("SimilarityLmax", "Maximum angular momentum for seminumerical computation", 6); if(argc==2) set.parse(argv[1]); else printf("Using default settings.\n"); set.print(); // Get the tolerance double tol=set.get_double("EMDTol"); // Load checkpoint Checkpoint chkpt(set.get_string("LoadChk"),false); // Load basis set BasisSet basis; chkpt.read(basis); // Load density matrix arma::cx_mat P; arma::mat Pr, Pi; chkpt.read("P",Pr); if(chkpt.exist("P_im")) { chkpt.read("P_im",Pi); P=Pr*COMPLEX1 + Pi*COMPLEXI; } else P=Pr*COMPLEX1; // The projection to calculate int l=0, m=0; std::string lmstr=set.get_string("EMDlm"); if(lmstr.size()) { // Get l and m values std::vector<std::string> lmval=splitline(lmstr); if(lmval.size()!=2) throw std::runtime_error("Invalid specification of l and m values.\n"); l=readint(lmval[0]); m=readint(lmval[1]); } bool adaptive=set.get_bool("EMDAdapt"); // Compute orbital EMDs? if(set.get_string("EMDOrbitals")!="") { // Get orbitals std::vector<std::string> orbs=splitline(set.get_string("EMDOrbitals")); // Polarized calculation? bool restr; chkpt.read("Restricted",restr); if(restr!= (orbs.size()==1)) throw std::runtime_error("Invalid occupancies for spin alpha and beta!\n"); if(l!=0) printf("\nComputing the (%i %+i) projection of the orbital EMD.\n",l,m); for(size_t ispin=0;ispin<orbs.size();ispin++) { // Indices of orbitals to include. std::vector<size_t> idx=parse_range(orbs[ispin]); // Change into C++ indexing for(size_t i=0;i<idx.size();i++) idx[i]--; // Read orbitals arma::mat C; if(restr) chkpt.read("C",C); else { if(ispin==0) chkpt.read("Ca",C); else chkpt.read("Cb",C); } for(size_t i=0;i<idx.size();i++) { // Names of output files char emdname[80]; char momname[80]; char Jname[80]; char Jintname[80]; char suffix[80]; if(l==0) sprintf(suffix,".txt"); else sprintf(suffix,"_%i_%i.txt",l,m); if(restr) { sprintf(emdname,"emd-%i%s",(int) idx[i]+1,suffix); sprintf(momname,"moments-%i%s",(int) idx[i]+1,suffix); sprintf(Jname,"compton-%i%s",(int) idx[i]+1,suffix); sprintf(Jintname,"compton-interp-%i%s",(int) idx[i]+1,suffix); } else { if(ispin==0) { sprintf(emdname,"emd-a-%i%s",(int) idx[i]+1,suffix); sprintf(momname,"moments-a-%i%s",(int) idx[i]+1,suffix); sprintf(Jname,"compton-a-%i%s",(int) idx[i]+1,suffix); sprintf(Jintname,"compton-interp-a-%i%s",(int) idx[i]+1,suffix); } else { sprintf(emdname,"emd-b-%i%s",(int) idx[i]+1,suffix); sprintf(momname,"moments-b-%i%s",(int) idx[i]+1,suffix); sprintf(Jname,"compton-b-%i%s",(int) idx[i]+1,suffix); sprintf(Jintname,"compton-interp-b-%i%s",(int) idx[i]+1,suffix); } } // Generate dummy density matrix arma::cx_mat Pdum=C.col(idx[i])*arma::trans(C.col(idx[i]))*COMPLEX1; Timer temd; GaussianEMDEvaluator *poseval=new GaussianEMDEvaluator(basis,Pdum,l,std::abs(m)); GaussianEMDEvaluator *negeval; if(m!=0) negeval=new GaussianEMDEvaluator(basis,Pdum,l,-std::abs(m)); else negeval=NULL; EMD emd(poseval, negeval, 1, l, m); if(adaptive) { emd.initial_fill(); if(l==0 && m==0) emd.find_electrons(); emd.optimize_moments(true,tol); } else emd.fixed_fill(); emd.save(emdname); emd.moments(momname); if(l==0 && m==0) { emd.compton_profile(Jname); emd.compton_profile_interp(Jintname); } delete poseval; if(m!=0) delete negeval; } } } if(set.get_bool("DoEMD")) { t.print_time(); printf("\nCalculating EMD properties.\n"); printf("Please read and cite the reference:\n%s\n%s\n%s\n", \ "J. Lehtola, M. Hakala, J. Vaara and K. Hämäläinen", \ "Calculation of isotropic Compton profiles with Gaussian basis sets", \ "Phys. Chem. Chem. Phys. 13 (2011), pp. 5630 - 5641."); if(l!=0) printf("\nComputing the (%i %+i) projection of the EMD.\n",l,m); else printf("\nComputing the isotropic projection of the EMD.\n"); // Amount of electrons is int Nel; chkpt.read("Nel",Nel); // Construct EMD evaluators Timer temd; GaussianEMDEvaluator *poseval=new GaussianEMDEvaluator(basis,P,l,std::abs(m)); GaussianEMDEvaluator *negeval; if(m!=0) negeval=new GaussianEMDEvaluator(basis,P,l,-std::abs(m)); else negeval=NULL; temd.set(); EMD emd(poseval, negeval, Nel, l, m); if(adaptive) { emd.initial_fill(); if(l==0 && m==0) emd.find_electrons(); emd.optimize_moments(true,tol); } else emd.fixed_fill(); if(l==0 && m==0) { emd.save("emd.txt"); emd.moments("moments.txt"); emd.compton_profile("compton.txt"); emd.compton_profile_interp("compton-interp.txt"); } else { char fname[80]; sprintf(fname,"emd_%i_%i.txt",l,m); emd.save(fname); sprintf(fname,"moments_%i_%i.txt",l,m); emd.moments(fname); } if(l==0 && m==0) printf("Calculating isotropic EMD properties took %s.\n",temd.elapsed().c_str()); else printf("Calculating projected EMD properties took %s.\n",temd.elapsed().c_str()); delete poseval; if(m!=0) delete negeval; } // Do EMD on a cube? if(stricmp(set.get_string("EMDCube"),"")!=0) { t.print_time(); Timer temd; // Form grid in p space. std::vector<double> px, py, pz; parse_cube(set.get_string("EMDCube"),px,py,pz); // Calculate EMD on cube emd_cube(basis,P,px,py,pz); printf("Calculating EMD on a cube took %s.\n",temd.elapsed().c_str()); } // Compute similarity? if(stricmp(set.get_string("Similarity"),"")!=0) { // Load checkpoint Checkpoint simchk(set.get_string("Similarity"),false); // Get grid size std::vector<std::string> gridsize=splitline(set.get_string("SimilarityGrid")); if(gridsize.size()!=2) { throw std::runtime_error("Invalid grid size!\n"); } int nrad=readint(gridsize[0]); int lmax=readint(gridsize[1]); int radlmax=set.get_int("SimilarityLmax"); // Load basis set BasisSet simbas; simchk.read(simbas); // Load density matrix arma::mat simPr, simPi; arma::cx_mat simP; simchk.read("P",simPr); if(simchk.exist("P_im")) { simchk.read("P_im",simPi); simP=simPr*COMPLEX1 + simPi*COMPLEXI; } else simP=simPr*COMPLEX1; // Compute momentum density overlap arma::cube ovl; if(set.get_bool("SimilarityLM")) ovl=emd_overlap_semi(basis,P,simbas,simP,nrad,radlmax); else ovl=emd_overlap(basis,P,simbas,simP,nrad,lmax); // Amount of electrons int Nela, Nelb; chkpt.read("Nel", Nela); simchk.read("Nel", Nelb); // Shape function overlap arma::cube sh=emd_similarity(ovl,Nela,Nelb); sh.slice(0).save("similarity.dat",arma::raw_ascii); sh.slice(1).save("similarity_avg.dat",arma::raw_ascii); for(int s=0;s<2;s++) { if(s) { printf("%2s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\n","k","S0(AA)","S0(BB)","S0(AB)","I0(AA)","I0(BB)","I0(AB)","D0(AB)"); for(int k=-1;k<3;k++) // Vandenbussche don't include p^2 in the spherical average printf("%2i\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n", k+1, sh(k+1,0,s), sh(k+1,1,s), sh(k+1,2,s), sh(k+1,3,s), sh(k+1,4,s), sh(k+1,5,s), sh(k+1,6,s)); } else { printf("%2s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\t%9s\n","k","S(AA)","S(BB)","S(AB)","I(AA)","I(BB)","I(AB)","D(AB)"); for(int k=-1;k<3;k++) printf("%2i\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n", k, sh(k+1,0,s), sh(k+1,1,s), sh(k+1,2,s), sh(k+1,3,s), sh(k+1,4,s), sh(k+1,5,s), sh(k+1,6,s)); } printf("\n"); } } return 0; }
/** * gst_rtsp_transport_parse: * @str: a transport string * @transport: a #GstRTSPTransport * * Parse the RTSP transport string @str into @transport. * * Returns: a #GstRTSPResult. */ GstRTSPResult gst_rtsp_transport_parse (const gchar * str, GstRTSPTransport * transport) { gchar **split, *down, **transp = NULL; guint transport_params = 0; gint i, count; g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL); g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL); gst_rtsp_transport_init (transport); /* case insensitive */ down = g_ascii_strdown (str, -1); split = g_strsplit (down, ";", 0); g_free (down); /* First field contains the transport/profile/lower_transport */ if (split[0] == NULL) goto invalid_transport; transp = g_strsplit (split[0], "/", 0); if (transp[0] == NULL || transp[1] == NULL) goto invalid_transport; for (i = 0; transports[i].name; i++) if (strcmp (transp[0], transports[i].name) == 0) break; transport->trans = transports[i].mode; if (transport->trans != GST_RTSP_TRANS_RDT) { for (i = 0; profiles[i].name; i++) if (strcmp (transp[1], profiles[i].name) == 0) break; transport->profile = profiles[i].profile; count = 2; } else { /* RDT has transport/lower_transport */ transport->profile = GST_RTSP_PROFILE_AVP; count = 1; } if (transp[count] != NULL) { for (i = 0; ltrans[i].name; i++) if (strcmp (transp[count], ltrans[i].name) == 0) break; transport->lower_transport = ltrans[i].ltrans; } else { /* specifying the lower transport is optional */ transport->lower_transport = get_default_lower_trans (transport); } g_strfreev (transp); transp = NULL; if (transport->trans == GST_RTSP_TRANS_UNKNOWN || transport->profile == GST_RTSP_PROFILE_UNKNOWN || transport->lower_transport == GST_RTSP_LOWER_TRANS_UNKNOWN) goto unsupported_transport; i = 1; while (split[i]) { if (strcmp (split[i], "multicast") == 0) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY); if (transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP) goto invalid_transport; transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST; } else if (strcmp (split[i], "unicast") == 0) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY); if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP; } else if (g_str_has_prefix (split[i], "destination=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DESTINATION); transport->destination = g_strdup (split[i] + 12); } else if (g_str_has_prefix (split[i], "source=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SOURCE); transport->source = g_strdup (split[i] + 7); } else if (g_str_has_prefix (split[i], "layers=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_LAYERS); transport->layers = strtoul (split[i] + 7, NULL, 10); } else if (g_str_has_prefix (split[i], "mode=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_MODE); parse_mode (transport, split[i] + 5); if (!transport->mode_play && !transport->mode_record) goto invalid_transport; } else if (strcmp (split[i], "append") == 0) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_APPEND); transport->append = TRUE; } else if (g_str_has_prefix (split[i], "interleaved=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_INTERLEAVED); parse_range (split[i] + 12, &transport->interleaved); if (!IS_VALID_INTERLEAVE_RANGE (transport->interleaved)) goto invalid_transport; } else if (g_str_has_prefix (split[i], "ttl=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_TTL); transport->ttl = strtoul (split[i] + 4, NULL, 10); if (transport->ttl >= 256) goto invalid_transport; } else if (g_str_has_prefix (split[i], "port=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_PORT); if (parse_range (split[i] + 5, &transport->port)) { if (!IS_VALID_PORT_RANGE (transport->port)) goto invalid_transport; } } else if (g_str_has_prefix (split[i], "client_port=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_CLIENT_PORT); if (parse_range (split[i] + 12, &transport->client_port)) { if (!IS_VALID_PORT_RANGE (transport->client_port)) goto invalid_transport; } } else if (g_str_has_prefix (split[i], "server_port=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SERVER_PORT); if (parse_range (split[i] + 12, &transport->server_port)) { if (!IS_VALID_PORT_RANGE (transport->server_port)) goto invalid_transport; } } else if (g_str_has_prefix (split[i], "ssrc=")) { RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SSRC); transport->ssrc = strtoul (split[i] + 5, NULL, 16); } else { /* unknown field... */ if (strlen (split[i]) > 0) { g_warning ("unknown transport field \"%s\"", split[i]); } } i++; } g_strfreev (split); return GST_RTSP_OK; unsupported_transport: { g_strfreev (split); return GST_RTSP_ERROR; } invalid_transport: { g_strfreev (transp); g_strfreev (split); return GST_RTSP_EINVAL; } }
static void test_parse_range(void) { unsigned lower, upper; /* Successful cases */ assert_se(parse_range("111", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 111); assert_se(parse_range("111-123", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 123); assert_se(parse_range("123-111", &lower, &upper) == 0); assert_se(lower == 123); assert_se(upper == 111); assert_se(parse_range("123-123", &lower, &upper) == 0); assert_se(lower == 123); assert_se(upper == 123); assert_se(parse_range("0", &lower, &upper) == 0); assert_se(lower == 0); assert_se(upper == 0); assert_se(parse_range("0-15", &lower, &upper) == 0); assert_se(lower == 0); assert_se(upper == 15); assert_se(parse_range("15-0", &lower, &upper) == 0); assert_se(lower == 15); assert_se(upper == 0); assert_se(parse_range("128-65535", &lower, &upper) == 0); assert_se(lower == 128); assert_se(upper == 65535); assert_se(parse_range("1024-4294967295", &lower, &upper) == 0); assert_se(lower == 1024); assert_se(upper == 4294967295); /* Leading whitespace is acceptable */ assert_se(parse_range(" 111", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 111); assert_se(parse_range(" 111-123", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 123); assert_se(parse_range("111- 123", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 123); assert_se(parse_range("\t111-\t123", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 123); assert_se(parse_range(" \t 111- \t 123", &lower, &upper) == 0); assert_se(lower == 111); assert_se(upper == 123); /* Error cases, make sure they fail as expected */ lower = upper = 9999; assert_se(parse_range("111garbage", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("garbage111", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("garbage", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123garbage", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111garbage-123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* Empty string */ lower = upper = 9999; assert_se(parse_range("", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* 111--123 will pass -123 to safe_atou which returns -ERANGE for negative */ assert_se(parse_range("111--123", &lower, &upper) == -ERANGE); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("-111-123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123-", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111.4-123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123.4", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111,4-123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123,4", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* Error on trailing dash */ assert_se(parse_range("111-", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123-", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111--", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111- ", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* Whitespace is not a separator */ assert_se(parse_range("111 123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111\t123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111 \t 123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* Trailing whitespace is invalid (from safe_atou) */ assert_se(parse_range("111 ", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111-123 ", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111 -123", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111 -123 ", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111\t-123\t", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); assert_se(parse_range("111 \t -123 \t ", &lower, &upper) == -EINVAL); assert_se(lower == 9999); assert_se(upper == 9999); /* Out of the "unsigned" range, this is 1<<64 */ assert_se(parse_range("0-18446744073709551616", &lower, &upper) == -ERANGE); assert_se(lower == 9999); assert_se(upper == 9999); }
void parse_ret(char *ptr,nsp_ret_t *ret_t){ cJSON *json; json=cJSON_Parse((char *)ptr); if(!json || !json->child){ret_t->nsp_upcmd=UNKNOWN;return ;} cJSON *obj=json->child; bool has_upcmd=false; while(obj!=NULL){ if(strcmp(obj->string,"nsp_upcmd")==0){ has_upcmd=true; if(strcmp(obj->valuestring,"REQTCON")==0) {ret_t->nsp_upcmd = REQTCON;} else if(strcmp(obj->valuestring,"UPSTAT")==0) {ret_t->nsp_upcmd = UPSTAT;} else if(strcmp(obj->valuestring,"REQTBLK")==0) {ret_t->nsp_upcmd = REQTBLK;} else if(strcmp(obj->valuestring,"REQTSEG")==0) {ret_t->nsp_upcmd = REQTSEG;} else {ret_t->nsp_upcmd = UNKNOWN;cJSON_Delete(json);return;} } else if(strcmp(obj->string,"nsp_fid")==0){ strncpy(ret_t->nsp_fid,obj->valuestring, 32); ret_t->nsp_fid[32] = 0; } else if(strcmp(obj->string,"nsp_range")==0){ parse_range(obj->valuestring, &ret_t->nsp_range); } else if(strcmp(obj->string,"nsp_upstat")==0){ if(strcmp("FIN",obj->valuestring) == 0) {ret_t->nsp_upstat = FIN;} else if(strcmp("RECV",obj->valuestring) == 0) {ret_t->nsp_upstat = RECV;} else if(strcmp("NONE",obj->valuestring) == 0) {ret_t->nsp_upstat = NONE;} else {ret_t->nsp_upstat = UNKNOWN_UPSTAT;cJSON_Delete(json);return;} } else if(strcmp(obj->string,"nsp_fstat")==0){ cJSON *chi = obj->child; while(chi!=NULL){ if(strcmp(chi->string,"RSIZE")==0){ ret_t->nsp_fstat_rsize = chi->valueint; } chi=chi->next; } ret_t->nsp_fstat_rsize = 0; } else if(strcmp(obj->string,"nsp_path")==0){ strcpy(ret_t->nsp_path,obj->valuestring); } else if(strcmp(obj->string,"nsp_ts")==0){ ret_t->nsp_ts=obj->valueint; } else if(strcmp(obj->string,"nsp_size")==0){ strcpy(ret_t->nsp_size,obj->valuestring); } else if(strcmp(obj->string,"nsp_sig")==0){ strcpy(ret_t->nsp_sig,obj->valuestring); } else if(strcmp(obj->string,"nsp_segsize")==0){ ret_t->nsp_segsize=obj->valueint; } else{} obj=obj->next; } if(!has_upcmd){ ret_t->nsp_upcmd = UNKNOWN; } cJSON_Delete(json); }
int gt_parse_range(GtRange *range, const char *start, const char *end, unsigned int line_number, const char *filename, GtError *err) { return parse_range(range, start, end, line_number, filename, false, false, err); }
int server_partial_file_request(struct httpd *env, struct client *clt, char *path, struct stat *st, char *range_str) { struct server_config *srv_conf = clt->clt_srv_conf; struct http_descriptor *resp = clt->clt_descresp; struct http_descriptor *desc = clt->clt_descreq; struct media_type *media, multipart_media; struct range *range; struct evbuffer *evb = NULL; size_t content_length; int code = 500, fd = -1, i, nranges, ret; uint32_t boundary; char content_range[64]; const char *errstr = NULL; /* Ignore range request for methods other than GET */ if (desc->http_method != HTTP_METHOD_GET) return server_file_request(env, clt, path, st); if ((range = parse_range(range_str, st->st_size, &nranges)) == NULL) { code = 416; (void)snprintf(content_range, sizeof(content_range), "bytes */%lld", st->st_size); errstr = content_range; goto abort; } /* Now open the file, should be readable or we have another problem */ if ((fd = open(path, O_RDONLY)) == -1) goto abort; media = media_find_config(env, srv_conf, path); if ((evb = evbuffer_new()) == NULL) { errstr = "failed to allocate file buffer"; goto abort; } if (nranges == 1) { (void)snprintf(content_range, sizeof(content_range), "bytes %lld-%lld/%lld", range->start, range->end, st->st_size); if (kv_add(&resp->http_headers, "Content-Range", content_range) == NULL) goto abort; content_length = range->end - range->start + 1; if (buffer_add_range(fd, evb, range) == 0) goto abort; } else { content_length = 0; boundary = arc4random(); /* Generate a multipart payload of byteranges */ while (nranges--) { if ((i = evbuffer_add_printf(evb, "\r\n--%ud\r\n", boundary)) == -1) goto abort; content_length += i; if ((i = evbuffer_add_printf(evb, "Content-Type: %s/%s\r\n", media->media_type, media->media_subtype)) == -1) goto abort; content_length += i; if ((i = evbuffer_add_printf(evb, "Content-Range: bytes %lld-%lld/%lld\r\n\r\n", range->start, range->end, st->st_size)) == -1) goto abort; content_length += i; if (buffer_add_range(fd, evb, range) == 0) goto abort; content_length += range->end - range->start + 1; range++; } if ((i = evbuffer_add_printf(evb, "\r\n--%ud--\r\n", boundary)) == -1) goto abort; content_length += i; /* prepare multipart/byteranges media type */ (void)strlcpy(multipart_media.media_type, "multipart", sizeof(multipart_media.media_type)); (void)snprintf(multipart_media.media_subtype, sizeof(multipart_media.media_subtype), "byteranges; boundary=%ud", boundary); media = &multipart_media; } close(fd); fd = -1; ret = server_response_http(clt, 206, media, content_length, MINIMUM(time(NULL), st->st_mtim.tv_sec)); switch (ret) { case -1: goto fail; case 0: /* Connection is already finished */ evbuffer_free(evb); evb = NULL; goto done; default: break; } if (server_bufferevent_write_buffer(clt, evb) == -1) goto fail; evbuffer_free(evb); evb = NULL; bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE); if (clt->clt_persist) clt->clt_toread = TOREAD_HTTP_HEADER; else clt->clt_toread = TOREAD_HTTP_NONE; clt->clt_done = 0; done: server_reset_http(clt); return (0); fail: bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); bufferevent_free(clt->clt_bev); clt->clt_bev = NULL; abort: if (fd != -1) close(fd); if (errstr == NULL) errstr = strerror(errno); server_abort_http(clt, code, errstr); return (-1); }
int parse_command_line(struct modbus_params_t *params, int argc, char **argv) { int rs; int rc = RESULT_OK; int option_index; if (argc < 2) { ERR("%s: Could not parse arguments\n", argv[0]); print_help(); return RESULT_WRONG_ARG; }; load_defaults(params); while (1) { rs = getopt_long(argc, argv, short_options, long_options, &option_index); if (rs == -1) break; switch (rs) { case 'v': params->verbose++; dbg_set_level(params->verbose); break; case 'h': print_help(); return RESULT_PRINT_HELP; /* MODBUS TCP */ case 'H': params->host = optarg; break; case 'p': params->mport = optarg; break; #if LIBMODBUS_VERSION_MAJOR >= 3 /* MODBUS RTU */ case 'S': params->serial = optarg; break; case OPT_SERIAL_MODE: rc = parse_int_param(optarg, ¶ms->serial_mode); break; case 'b': rc = parse_int_param(optarg, ¶ms->serial_bps); break; case OPT_SERIAL_PARITY: params->serial_parity = (optarg) ? toupper(*optarg) : '\0'; break; case OPT_SERIAL_DATA_BITS: rc = parse_int_param(optarg, ¶ms->serial_data_bits); break; case OPT_SERIAL_STOP_BITS: rc = parse_int_param(optarg, ¶ms->serial_stop_bits); break; #endif case OPT_FILE: params->file = optarg; break; case 'd': rc = parse_int_param(optarg, ¶ms->devnum); break; case 'a': rc = parse_int_param(optarg, ¶ms->sad); if (params->sad <= 0) { ERR("Address should be greater than zero: %s\n", optarg); rc = RESULT_WRONG_ARG; } params->sad--; /* register/bit address starts from 0 */ break; case 'f': rc = parse_int_param(optarg, ¶ms->nf); break; case 'F': rc = parse_int_param(optarg, ¶ms->format); break; case 'w': if (parse_range(optarg, ¶ms->warn_range) != 0) { ERR("can't parse warning range %s\n", optarg); rc = RESULT_WRONG_ARG; } break; case 'c': if (parse_range(optarg, ¶ms->crit_range) != 0) { ERR("can't parse critical range %s\n", optarg); rc = RESULT_WRONG_ARG; } break; case 'n': params->nc = 1; break; case 'i': params->inverse_words = 1; break; case 's': params->swap_bytes = 1; break; case 't': rc = parse_int_param(optarg, ¶ms->tries); break; case 'N': params->nnc = 1; break; case 'm': rc = parse_double_param(optarg, ¶ms->perf_min); params->perf_min_en = 1; break; case 'M': rc = parse_double_param(optarg, ¶ms->perf_max); params->perf_max_en = 1; break; case 'L': params->perf_label = optarg; break; case 'P': params->perf_data = 1; break; case OPT_DUMP_FILE: params->dump_file = optarg; break; case OPT_DUMP: params->dump = 1; break; case OPT_DUMP_SIZE: rc = parse_int_param(optarg, ¶ms->dump_size); break; case OPT_DUMP_FORMAT: rc = parse_int_param(optarg, ¶ms->dump_format); switch (params->dump_format) { case DUMP_FMT_BIN: params->format = FORMAT_DUMP_BIN; break; case DUMP_FMT_HEX: params->format = FORMAT_DUMP_HEX; break; case DUMP_FMT_DEC: params->format = FORMAT_DUMP_DEC; break; } break; case OPT_LOCK_FILE_IN: params->lock_file_in = optarg; break; case OPT_LOCK_FILE_OUT: params->lock_file_out = optarg; break; case OPT_GAIN: rc = parse_double_param(optarg, ¶ms->gain); break; case OPT_OFFSET: rc = parse_double_param(optarg, ¶ms->offset); break; case OPT_VERSION: print_version(); rc = RESULT_PRINT_HELP; break; case '?': default: rc = RESULT_PRINT_HELP; }; if (rc != RESULT_OK) return rc; }; /* while(1) */ return check_command_line(params, argc, argv); }
bool CHttpServer::send_file(String const &path, HeaderList const &hdrs) { String fullPath = CFilePath::normalizePath(path); if (String_startsWith(fullPath,"/app/db/db-files") ) fullPath = CFilePath::join( rho_native_rhodbpath(), path.substr(4) ); else if (fullPath.find(m_root) != 0 && fullPath.find(m_strRhoRoot) != 0 && fullPath.find(m_strRuntimeRoot) != 0 && fullPath.find(m_userroot) != 0 && fullPath.find(m_strRhoUserRoot) != 0) fullPath = CFilePath::join( m_root, path ); struct stat st; bool bCheckExist = true; #ifdef RHODES_EMULATOR String strPlatform = RHOSIMCONF().getString("platform"); if ( strPlatform.length() > 0 ) { String fullPath1 = fullPath; int nDot = fullPath1.rfind('.'); if ( nDot >= 0 ) fullPath1.insert(nDot, String(".") + strPlatform); else fullPath1 += String(".") + strPlatform; if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { fullPath = fullPath1; bCheckExist = false; } } #endif bool doesNotExists = bCheckExist && (stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode)); if ( doesNotExists ) { // looking for files at 'rho/apps' at runtime folder fullPath = CFilePath::join( m_strRuntimeRoot, path ); } if (verbose) RAWTRACE1("Sending file %s...", fullPath.c_str()); if ( doesNotExists ) { if ( stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode) ) { doesNotExists = true; }else doesNotExists = false; } #ifdef RHODES_EMULATOR if ( doesNotExists ) { CTokenizer oTokenizer( RHOSIMCONF().getString("ext_path"), ";" ); while (oTokenizer.hasMoreTokens()) { String tok = oTokenizer.nextToken(); tok = String_trim(tok); String fullPath1 = CFilePath::join( tok, path ); if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { fullPath = fullPath1; doesNotExists = false; break; } } } #endif if ( doesNotExists ) { RAWLOG_ERROR1("The file %s was not found", path.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } PROF_START("LOW_FILE"); FILE *fp = fopen(fullPath.c_str(), "rb"); PROF_STOP("LOW_FILE"); if (!fp) { RAWLOG_ERROR1("The file %s could not be opened", path.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " could not be opened.</font></html"; send_response(create_response("404 Not Found",error)); return false; } HeaderList headers; // Detect mime type headers.push_back(Header("Content-Type", get_mime_type(path))); if ( String_startsWith(path, "/public") ) { headers.push_back(Header("Expires", "Thu, 15 Apr 2020 20:00:00 GMT") ); headers.push_back(Header("Cache-Control", "max-age=2592000") ); } // Content length char* buf = new char[FILE_BUF_SIZE]; String start_line; size_t file_size = st.st_size; size_t range_begin = 0, range_end = file_size - 1; size_t content_size = file_size; if (parse_range(hdrs, &range_begin, &range_end)) { if (range_end >= file_size) range_end = file_size - 1; if (range_begin >= range_end) range_begin = range_end - 1; content_size = range_end - range_begin + 1; if (fseek(fp, range_begin, SEEK_SET) == -1) { RAWLOG_ERROR1("Can not seek to specified range start: %lu", (unsigned long)range_begin); snprintf(buf, FILE_BUF_SIZE, "bytes */%lu", (unsigned long)file_size); headers.push_back(Header("Content-Range", buf)); send_response(create_response("416 Request Range Not Satisfiable",headers)); fclose(fp); delete buf; return false; } snprintf(buf, FILE_BUF_SIZE, "bytes %lu-%lu/%lu", (unsigned long)range_begin, (unsigned long)range_end, (unsigned long)file_size); headers.push_back(Header("Content-Range", buf)); start_line = "206 Partial Content"; } else { start_line = "200 OK"; } snprintf(buf, FILE_BUF_SIZE, "%lu", (unsigned long)content_size); headers.push_back(Header("Content-Length", buf)); // Send headers if (!send_response(create_response(start_line, headers))) { RAWLOG_ERROR1("Can not send headers while sending file %s", path.c_str()); fclose(fp); delete buf; return false; } // Send body for (size_t start = range_begin; start < range_end + 1;) { size_t need_to_read = range_end - start + 1; if (need_to_read == 0) break; if (need_to_read > FILE_BUF_SIZE) need_to_read = FILE_BUF_SIZE; PROF_START("LOW_FILE"); size_t n = fread(buf, 1, need_to_read, fp);//fread(buf, 1, need_to_read, fp); PROF_STOP("LOW_FILE"); if (n < need_to_read) { if (ferror(fp) ) { RAWLOG_ERROR2("Can not read part of file (at position %lu): %s", (unsigned long)start, strerror(errno)); } else if ( feof(fp) ) { RAWLOG_ERROR1("End of file reached, but we expect data (%lu bytes)", (unsigned long)need_to_read); } fclose(fp); delete buf; return false; } start += n; if (!send_response_body(String(buf, n))) { RAWLOG_ERROR1("Can not send part of data while sending file %s", path.c_str()); fclose(fp); delete buf; return false; } } PROF_START("LOW_FILE"); fclose(fp); PROF_STOP("LOW_FILE"); delete buf; if (verbose) RAWTRACE1("File %s was sent successfully", path.c_str()); return false; }
static int parse_filters(char *filters, struct btrfs_balance_args *args) { char *this_char; char *value; char *save_ptr; if (!filters) return 0; for (this_char = strtok_r(filters, ",", &save_ptr); this_char != NULL; this_char = strtok_r(NULL, ",", &save_ptr)) { if ((value = strchr(this_char, '=')) != NULL) *value++ = 0; if (!strcmp(this_char, "profiles")) { if (!value || !*value) { fprintf(stderr, "the profiles filter requires " "an argument\n"); return 1; } if (parse_profiles(value, &args->profiles)) { fprintf(stderr, "Invalid profiles argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_PROFILES; } else if (!strcmp(this_char, "usage")) { if (!value || !*value) { fprintf(stderr, "the usage filter requires " "an argument\n"); return 1; } if (parse_u64(value, &args->usage) || args->usage > 100) { fprintf(stderr, "Invalid usage argument: %s\n", value); return 1; } args->flags |= BTRFS_BALANCE_ARGS_USAGE; } else if (!strcmp(this_char, "devid")) { if (!value || !*value) { fprintf(stderr, "the devid filter requires " "an argument\n"); return 1; } if (parse_u64(value, &args->devid) || args->devid == 0) { fprintf(stderr, "Invalid devid argument: %s\n", value); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DEVID; } else if (!strcmp(this_char, "drange")) { if (!value || !*value) { fprintf(stderr, "the drange filter requires " "an argument\n"); return 1; } if (parse_range(value, &args->pstart, &args->pend)) { fprintf(stderr, "Invalid drange argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_DRANGE; } else if (!strcmp(this_char, "vrange")) { if (!value || !*value) { fprintf(stderr, "the vrange filter requires " "an argument\n"); return 1; } if (parse_range(value, &args->vstart, &args->vend)) { fprintf(stderr, "Invalid vrange argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_VRANGE; } else if (!strcmp(this_char, "convert")) { if (!value || !*value) { fprintf(stderr, "the convert option requires " "an argument\n"); return 1; } if (parse_one_profile(value, &args->target)) { fprintf(stderr, "Invalid convert argument\n"); return 1; } args->flags |= BTRFS_BALANCE_ARGS_CONVERT; } else if (!strcmp(this_char, "soft")) { args->flags |= BTRFS_BALANCE_ARGS_SOFT; } else { fprintf(stderr, "Unrecognized balance option '%s'\n", this_char); return 1; } } return 0; }
/* Try to parse a hunk header in string HEADER, putting parsed information * into HUNK. Return TRUE if the header parsed correctly. ATAT is the * character string used to delimit the hunk header. * Do all allocations in POOL. */ static svn_boolean_t parse_hunk_header(const char *header, svn_diff_hunk_t *hunk, const char *atat, apr_pool_t *pool) { const char *p; const char *start; svn_stringbuf_t *range; p = header + strlen(atat); if (*p != ' ') /* No. */ return FALSE; p++; if (*p != '-') /* Nah... */ return FALSE; /* OK, this may be worth allocating some memory for... */ range = svn_stringbuf_create_ensure(31, pool); start = ++p; while (*p && *p != ' ') { p++; } if (*p != ' ') /* No no no... */ return FALSE; svn_stringbuf_appendbytes(range, start, p - start); /* Try to parse the first range. */ if (! parse_range(&hunk->original_start, &hunk->original_length, range->data)) return FALSE; /* Clear the stringbuf so we can reuse it for the second range. */ svn_stringbuf_setempty(range); p++; if (*p != '+') /* Eeek! */ return FALSE; /* OK, this may be worth copying... */ start = ++p; while (*p && *p != ' ') { p++; } if (*p != ' ') /* No no no... */ return FALSE; svn_stringbuf_appendbytes(range, start, p - start); /* Check for trailing @@ */ p++; if (! starts_with(p, atat)) return FALSE; /* There may be stuff like C-function names after the trailing @@, * but we ignore that. */ /* Try to parse the second range. */ if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data)) return FALSE; /* Hunk header is good. */ return TRUE; }
/* * Entry point of pg_arman command. */ int main(int argc, char *argv[]) { const char *cmd = NULL; const char *range1 = NULL; const char *range2 = NULL; pgBackupRange range; int i; /* do not buffer progress messages */ setvbuf(stdout, 0, _IONBF, 0); /* TODO: remove this */ /* initialize configuration */ catalog_init_config(¤t); /* overwrite configuration with command line arguments */ i = pgut_getopt(argc, argv, options); for (; i < argc; i++) { if (cmd == NULL) cmd = argv[i]; else if (range1 == NULL) range1 = argv[i]; else if (range2 == NULL) range2 = argv[i]; else elog(ERROR, "too many arguments"); } /* command argument (backup/restore/show/...) is required. */ if (cmd == NULL) { help(false); return 1; } /* get object range argument if any */ if (range1 && range2) parse_range(&range, range1, range2); else if (range1) parse_range(&range, range1, ""); else range.begin = range.end = 0; /* Read default configuration from file. */ if (backup_path) { char path[MAXPGPATH]; /* Check if backup_path is directory. */ struct stat stat_buf; int rc = stat(backup_path, &stat_buf); /* If rc == -1, there is no file or directory. So it's OK. */ if (rc != -1 && !S_ISDIR(stat_buf.st_mode)) elog(ERROR, "-B, --backup-path must be a path to directory"); join_path_components(path, backup_path, PG_RMAN_INI_FILE); pgut_readopt(path, options, ERROR); } /* BACKUP_PATH is always required */ if (backup_path == NULL) elog(ERROR, "required parameter not specified: BACKUP_PATH (-B, --backup-path)"); /* path must be absolute */ if (backup_path != NULL && !is_absolute_path(backup_path)) elog(ERROR, "-B, --backup-path must be an absolute path"); if (pgdata != NULL && !is_absolute_path(pgdata)) elog(ERROR, "-D, --pgdata must be an absolute path"); if (arclog_path != NULL && !is_absolute_path(arclog_path)) elog(ERROR, "-A, --arclog-path must be an absolute path"); /* Sanity checks with commands */ if (pg_strcasecmp(cmd, "delete") == 0 && arclog_path == NULL) elog(ERROR, "delete command needs ARCLOG_PATH (-A, --arclog-path) to be set"); /* setup exclusion list for file search */ for (i = 0; pgdata_exclude[i]; i++) /* find first empty slot */ ; if (arclog_path) pgdata_exclude[i++] = arclog_path; /* do actual operation */ if (pg_strcasecmp(cmd, "init") == 0) return do_init(); else if (pg_strcasecmp(cmd, "backup") == 0) { pgBackupOption bkupopt; int res; bkupopt.smooth_checkpoint = smooth_checkpoint; bkupopt.keep_data_generations = keep_data_generations; bkupopt.keep_data_days = keep_data_days; /* Do the backup */ res = do_backup(bkupopt); if (res != 0) return res; /* If validation has been requested, do it */ range.begin = current.start_time; range.end = current.start_time + 1; if (backup_validate) do_validate(&range); } else if (pg_strcasecmp(cmd, "restore") == 0) return do_restore(target_time, target_xid, target_inclusive, target_tli); else if (pg_strcasecmp(cmd, "show") == 0) return do_show(&range, show_all); else if (pg_strcasecmp(cmd, "validate") == 0) return do_validate(&range); else if (pg_strcasecmp(cmd, "delete") == 0) return do_delete(&range); else elog(ERROR, "invalid command \"%s\"", cmd); return 0; }
/* FIXME: This function does not handle LONG_LONG */ int _pSLang_sscanf (void) { int num; unsigned int num_refs; char *format; char *input_string, *input_string_max; SLFUTURE_CONST char *f, *s; unsigned char map8[256], map10[256], map16[256]; if (SLang_Num_Function_Args < 2) { _pSLang_verror (SL_INVALID_PARM, "Int_Type sscanf (str, format, ...)"); return -1; } num_refs = (unsigned int) SLang_Num_Function_Args; if (-1 == SLreverse_stack (num_refs)) return -1; num_refs -= 2; if (-1 == SLang_pop_slstring (&input_string)) return -1; if (-1 == SLang_pop_slstring (&format)) { SLang_free_slstring (input_string); return -1; } f = format; s = input_string; input_string_max = input_string + strlen (input_string); init_map (map8, 8); init_map (map10, 10); init_map (map16, 16); num = 0; while (num_refs != 0) { SLang_Object_Type obj; SLang_Ref_Type *ref; SLFUTURE_CONST char *smax; unsigned char *map; int base; int no_assign; int is_short; int is_long; int status; char chf; unsigned int width; int has_width; chf = *f++; if (chf == 0) { /* Hmmm.... what is the most useful thing to do?? */ #if 1 break; #else _pSLang_verror (SL_INVALID_PARM, "sscanf: format not big enough for output list"); goto return_error; #endif } if (isspace (chf)) { char *s1 = _pSLskip_whitespace (s); if (s1 == s) break; s = s1; continue; } if ((chf != '%') || ((chf = *f++) == '%')) { if (*s != chf) break; s++; continue; } no_assign = 0; is_short = 0; is_long = 0; width = 0; smax = input_string_max; /* Look for the flag character */ if (chf == '*') { no_assign = 1; chf = *f++; } /* Width */ has_width = isdigit (chf); if (has_width) { f--; (void) parse_uint (&f, f + strlen(f), &width, 10, map10); chf = *f++; } /* Now the type modifier */ switch (chf) { case 'h': is_short = 1; chf = *f++; break; case 'L': /* not implemented */ case 'l': is_long = 1; chf = *f++; break; } status = -1; if ((chf != 'c') && (chf != '[')) { s = _pSLskip_whitespace (s); if (*s == 0) break; } if (has_width) { if (width > (unsigned int) (input_string_max - s)) width = (unsigned int) (input_string_max - s); smax = s + width; } /* Now the format descriptor */ map = map10; base = 10; try_again: /* used by i, x, and o, conversions */ switch (chf) { case 0: _pSLang_verror (SL_INVALID_PARM, "sscanf: Unexpected end of format"); goto return_error; case 'D': is_long = 1; case 'd': if (is_short) { obj.o_data_type = SLANG_SHORT_TYPE; status = parse_short (&s, smax, &obj.v.short_val, base, map); } else if (is_long) { obj.o_data_type = SLANG_LONG_TYPE; status = parse_long (&s, smax, &obj.v.long_val, base, map); } else { obj.o_data_type = SLANG_INT_TYPE; status = parse_int (&s, smax, &obj.v.int_val, base, map); } break; case 'U': is_long = 1; case 'u': if (is_short) { obj.o_data_type = SLANG_USHORT_TYPE; status = parse_ushort (&s, smax, &obj.v.ushort_val, base, map); } else if (is_long) { obj.o_data_type = SLANG_ULONG_TYPE; status = parse_ulong (&s, smax, &obj.v.ulong_val, base, map); } else { obj.o_data_type = SLANG_INT_TYPE; status = parse_uint (&s, smax, &obj.v.uint_val, base, map); } break; case 'I': is_long = 1; case 'i': if ((s + 1 >= smax) || (*s != 0)) chf = 'd'; else if (((s[1] == 'x') || (s[1] == 'X')) && (s + 2 < smax)) { s += 2; chf = 'x'; } else chf = 'o'; goto try_again; case 'O': is_long = 1; case 'o': map = map8; base = 8; chf = 'd'; goto try_again; case 'X': is_long = 1; case 'x': base = 16; map = map16; chf = 'd'; goto try_again; case 'E': case 'F': is_long = 1; case 'e': case 'f': case 'g': #if SLANG_HAS_FLOAT if (is_long) { obj.o_data_type = SLANG_DOUBLE_TYPE; status = parse_double (&s, smax, &obj.v.double_val); } else { obj.o_data_type = SLANG_FLOAT_TYPE; status = parse_float (&s, smax, &obj.v.float_val); } #else _pSLang_verror (SL_NOT_IMPLEMENTED, "This version of the S-Lang does not support floating point"); status = -1; #endif break; case 's': obj.o_data_type = SLANG_STRING_TYPE; status = parse_string (&s, smax, &obj.v.s_val); break; case 'c': if (has_width == 0) { obj.o_data_type = SLANG_UCHAR_TYPE; obj.v.uchar_val = *s++; status = 1; break; } obj.o_data_type = SLANG_STRING_TYPE; status = parse_bstring (&s, smax, &obj.v.s_val); break; case '[': obj.o_data_type = SLANG_STRING_TYPE; status = parse_range (&s, smax, &f, &obj.v.s_val); break; case 'n': obj.o_data_type = SLANG_UINT_TYPE; obj.v.uint_val = (unsigned int) (s - input_string); status = 1; break; default: status = -1; _pSLang_verror (SL_NOT_IMPLEMENTED, "format specifier '%c' is not supported", chf); break; } if (status == 0) break; if (status == -1) goto return_error; if (no_assign) { SLang_free_object (&obj); continue; } if (-1 == SLang_pop_ref (&ref)) { SLang_free_object (&obj); goto return_error; } if (-1 == SLang_push (&obj)) { SLang_free_object (&obj); SLang_free_ref (ref); goto return_error; } if (-1 == _pSLang_deref_assign (ref)) { SLang_free_ref (ref); goto return_error; } SLang_free_ref (ref); num++; num_refs--; } if (-1 == SLdo_pop_n (num_refs)) goto return_error; SLang_free_slstring (format); SLang_free_slstring (input_string); return num; return_error: /* NULLS ok */ SLang_free_slstring (format); SLang_free_slstring (input_string); return -1; }