예제 #1
0
파일: resolv.c 프로젝트: Afterglow/ipxe
static int numeric_resolv ( struct interface *resolv,
			    const char *name, struct sockaddr *sa ) {
	struct numeric_resolv *numeric;
	struct sockaddr_in *sin;

	/* Allocate and initialise structure */
	numeric = zalloc ( sizeof ( *numeric ) );
	if ( ! numeric )
		return -ENOMEM;
	ref_init ( &numeric->refcnt, NULL );
	intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt );
	process_init ( &numeric->process, &numeric_process_desc,
		       &numeric->refcnt );
	memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) );

	DBGC ( numeric, "NUMERIC %p attempting to resolve \"%s\"\n",
	       numeric, name );

	/* Attempt to resolve name */
	sin = ( ( struct sockaddr_in * ) &numeric->sa );
	if ( inet_aton ( name, &sin->sin_addr ) != 0 ) {
		sin->sin_family = AF_INET;
	} else {
		numeric->rc = -EINVAL;
	}

	/* Attach to parent interface, mortalise self, and return */
	intf_plug_plug ( &numeric->resolv, resolv );
	ref_put ( &numeric->refcnt );
	return 0;
}
예제 #2
0
SOCK new_socket_wrapper()
{
	struct socket_wrapper *sw = calloc(1,sizeof(*sw));
	sw->status = SESTABLISH;
	ref_init(&sw->ref,0,destroy_socket_wrapper,1);
	return (SOCK)sw;
}
예제 #3
0
파일: rb_ogl3_context.c 프로젝트: vaplv/foo
/*******************************************************************************
 *
 * Render backend context functions.
 *
 ******************************************************************************/
int
rb_create_context
  (struct mem_allocator* specific_allocator,
   struct rb_context** out_ctxt)
{
  struct mem_allocator* allocator = NULL;
  struct rb_context* ctxt = NULL;
  int err = 0;

  if(!out_ctxt)
    goto error;

  allocator = specific_allocator ? specific_allocator : &mem_default_allocator;
  ctxt = MEM_CALLOC(allocator, 1, sizeof(struct rb_context));
  if(!ctxt)
    goto error;
  ctxt->allocator = allocator;
  ref_init(&ctxt->ref);

  setup_config(&ctxt->config);

exit:
  if(ctxt)
    *out_ctxt = ctxt;
  return err;

error:
  if(ctxt) {
    RB(context_ref_put(ctxt));
    ctxt = NULL;
  }
  err = -1;
  goto exit;
}
예제 #4
0
/**
 * Instantiate a downloader
 *
 * @v job		Job control interface
 * @v image		Image to fill with downloaded file
 * @v type		Location type to pass to xfer_open()
 * @v ...		Remaining arguments to pass to xfer_open()
 * @ret rc		Return status code
 *
 * Instantiates a downloader object to download the specified URI into
 * the specified image object.
 */
int create_downloader ( struct interface *job, struct image *image,
			int type, ... ) {
	struct downloader *downloader;
	va_list args;
	int rc;

	/* Allocate and initialise structure */
	downloader = zalloc ( sizeof ( *downloader ) );
	if ( ! downloader )
		return -ENOMEM;
	ref_init ( &downloader->refcnt, downloader_free );
	intf_init ( &downloader->job, &downloader_job_desc,
		    &downloader->refcnt );
	intf_init ( &downloader->xfer, &downloader_xfer_desc,
		    &downloader->refcnt );
	downloader->image = image_get ( image );
	va_start ( args, type );

	/* Instantiate child objects and attach to our interfaces */
	if ( ( rc = xfer_vopen ( &downloader->xfer, type, args ) ) != 0 )
		goto err;

	/* Attach parent interface, mortalise self, and return */
	intf_plug_plug ( &downloader->job, job );
	ref_put ( &downloader->refcnt );
	va_end ( args );
	return 0;

 err:
	downloader_finished ( downloader, rc );
	ref_put ( &downloader->refcnt );
	va_end ( args );
	return rc;
}
예제 #5
0
파일: zone.c 프로젝트: nice-redbull/knot
knot_zone_t *knot_zone_new_empty(knot_dname_t *name)
{
	if (!name) {
		return 0;
	}

	dbg_zone("Creating new zone!\n");

	knot_zone_t *zone = malloc(sizeof(knot_zone_t));
	if (zone == NULL) {
		ERR_ALLOC_FAILED;
		return NULL;
	}
	memset(zone, 0, sizeof(knot_zone_t));

	// save the zone name
	dbg_zone("Setting zone name.\n");
	zone->name = name;

	/* Initialize reference counting. */
	ref_init(&zone->ref, knot_zone_dtor);

	/* Set reference counter to 1, caller should release it after use. */
	knot_zone_retain(zone);

	return zone;
}
예제 #6
0
파일: edit_picking.c 프로젝트: vaplv/foo
/*******************************************************************************
 *
 * Picking functions
 *
 ******************************************************************************/
enum edit_error
edit_create_picking
  (struct app* app,
   struct edit_imgui* imgui,
   struct edit_model_instance_selection* instance_selection,
   struct mem_allocator* allocator,
   struct edit_picking** out_picking)
{
  struct edit_picking* picking = NULL;
  enum edit_error edit_err = EDIT_NO_ERROR;
  enum sl_error sl_err = SL_NO_ERROR;

  if(UNLIKELY(!app || !instance_selection || !allocator || !out_picking)) {
    edit_err = EDIT_INVALID_ARGUMENT;
    goto error;
  }

  picking = MEM_CALLOC(allocator, 1, sizeof(struct edit_picking));
  if(!picking) {
    edit_err = EDIT_MEMORY_ERROR;
    goto error;
  }
  ref_init(&picking->ref);
  APP(ref_get(app));
  picking->app = app;
  EDIT(imgui_ref_get(imgui));
  picking->imgui = imgui;
  EDIT(model_instance_selection_ref_get(instance_selection));
  picking->instance_selection = instance_selection;
  picking->allocator = allocator;

  sl_err = sl_create_hash_table
    (sizeof(uint32_t),
     ALIGNOF(uint32_t),
     sizeof(uint32_t),
     ALIGNOF(uint32_t),
     hash_uint32,
     eq_uint32,
     allocator,
     &picking->picked_instances_htbl);
  if(sl_err != SL_NO_ERROR) {
    edit_err = sl_to_edit_error(sl_err);
    goto error;
  }

exit:
  if(out_picking)
    *out_picking = picking;
  return edit_err;
error:
  if(picking) {
    EDIT(picking_ref_put(picking));
    picking = NULL;
  }
  goto exit;
}
예제 #7
0
파일: lsock.c 프로젝트: bigvaliant/nodelua
_lsock_t luasock_new(struct connection *c)
{
    _lsock_t sock = calloc(1,sizeof(*sock));
    ref_init(&sock->ref,type_asynsock,luasock_destroy,1);
    if(c){
        sock->c = c;
        c->usr_ptr = sock;
    }
    return sock;
}
예제 #8
0
파일: bytes.c 프로젝트: Suerg/matasano
struct bytes *bytes_create(int len)
{
	struct bytes *bytes = malloc(sizeof(*bytes));

	bytes->len = len;
	ref_init(&bytes->ref);
	bytes->data = malloc(len * sizeof(*(bytes->data)));

	return bytes;
}
예제 #9
0
struct connection *new_conn(SOCK s,uint8_t is_raw)
{
	struct connection *c = calloc(1,sizeof(*c));
	c->socket = s;
	c->recv_overlap.c = c;
	c->send_overlap.c = c;
	c->raw = is_raw;
	ref_init(&c->ref,0,connection_destroy,1);
    c->status = SESTABLISH;
	return c;
}
예제 #10
0
파일: buffer.c 프로젝트: Stan1990/KendyNet
static inline buffer_t buffer_create(uint32_t capacity)
{
	uint32_t size = sizeof(struct buffer) + capacity;
    buffer_t b = (buffer_t)ALLOC(buffer_allocator,size);
	if(b)
	{
		b->size = 0;
		b->capacity = capacity;
		ref_init(&b->_refbase,0,buffer_destroy,0);
	}
	return b;
}
예제 #11
0
파일: fcels.c 프로젝트: eatnumber1/ipxe
/**
 * Create ELS transaction
 *
 * @v port		Fibre Channel port
 * @v port_id		Local port ID
 * @v peer_port_id	Peer port ID
 * @ret els		Fibre Channel ELS transaction, or NULL
 */
static struct fc_els * fc_els_create ( struct fc_port *port,
                                       struct fc_port_id *port_id,
                                       struct fc_port_id *peer_port_id ) {
    struct fc_els *els;

    /* Allocate and initialise structure */
    els = zalloc ( sizeof ( *els ) );
    if ( ! els )
        return NULL;
    ref_init ( &els->refcnt, fc_els_free );
    intf_init ( &els->job, &fc_els_job_desc, &els->refcnt );
    intf_init ( &els->xchg, &fc_els_xchg_desc, &els->refcnt );
    process_init_stopped ( &els->process, &fc_els_process_desc,
                           &els->refcnt );
    els->port = fc_port_get ( port );
    memcpy ( &els->port_id, port_id, sizeof ( els->port_id ) );
    memcpy ( &els->peer_port_id, peer_port_id,
             sizeof ( els->peer_port_id ) );
    return els;
}
예제 #12
0
/*******************************************************************************
 *
 * Vertex array functions.
 *
 ******************************************************************************/
int
rb_create_vertex_array
  (struct rb_context* ctxt,
   struct rb_vertex_array** out_array)
{
  struct rb_vertex_array* array = NULL;

  if(!ctxt || !out_array)
    return -1;

  array = MEM_ALLOC(ctxt->allocator, sizeof(struct rb_vertex_array));
  if(!array)
    return -1;
  ref_init(&array->ref);
  RB(context_ref_get(ctxt));
  array->ctxt = ctxt;

  OGL(GenVertexArrays(1, &array->name));
  *out_array = array;
  return 0;
}
예제 #13
0
파일: resolv.c 프로젝트: 42wim/ipxe
static int numeric_resolv ( struct interface *resolv,
			    const char *name, struct sockaddr *sa ) {
	struct numeric_resolv *numeric;

	/* Allocate and initialise structure */
	numeric = zalloc ( sizeof ( *numeric ) );
	if ( ! numeric )
		return -ENOMEM;
	ref_init ( &numeric->refcnt, NULL );
	intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt );
	process_init ( &numeric->process, &numeric_process_desc,
		       &numeric->refcnt );
	memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) );

	/* Attempt to resolve name */
	numeric->rc = sock_aton ( name, &numeric->sa );

	/* Attach to parent interface, mortalise self, and return */
	intf_plug_plug ( &numeric->resolv, resolv );
	ref_put ( &numeric->refcnt );
	return 0;
}
예제 #14
0
파일: rb_ogl3_buffers.c 프로젝트: vaplv/rb
/*******************************************************************************
 *
 * Private functions.
 *
 ******************************************************************************/
int
rb_ogl3_create_buffer
  (struct rb_context* ctxt,
   const struct rb_ogl3_buffer_desc* desc,
   const void* init_data,
   struct rb_buffer** out_buffer)
{
  struct rb_buffer* buffer = NULL;

  if(!ctxt
  || !desc
  || !out_buffer
  || (desc->target == RB_OGL3_NB_BUFFER_TARGETS)
  || (desc->usage == RB_USAGE_IMMUTABLE && init_data == NULL))
    return -1;

  buffer = MEM_ALLOC(ctxt->allocator, sizeof(struct rb_buffer));
  if(!buffer)
    return -1;
  ref_init(&buffer->ref);
  RB(context_ref_get(ctxt));
  buffer->ctxt = ctxt;

  buffer->target = rb_to_ogl3_buffer_target(desc->target);
  buffer->usage = rb_to_ogl3_usage(desc->usage);
  buffer->size = (GLsizei)desc->size;
  buffer->binding = desc->target;

  OGL(GenBuffers(1, &buffer->name));
  OGL(BindBuffer(buffer->target, buffer->name));
  OGL(BufferData(buffer->target, buffer->size, init_data, buffer->usage));
  OGL(BindBuffer
    (buffer->target, 
     ctxt->state_cache.buffer_binding[buffer->binding]));

  *out_buffer = buffer;
  return 0;
}
예제 #15
0
파일: main.c 프로젝트: bonnefoa/junkie
static void all_init(void)
{
    log_init();
    files_init();
    ext_init();
    cli_init();
    mallocer_init();    // as all users do not init it...
    ref_init(); // as all users do not init it...
    hash_init();    // as all users do not init it...
    redim_array_init(); // if there are no users then some ext functions used by the www interface won't be defined
    os_detect_init();   // dummy function just to include os_detect in junkie (that does not use it, but plugins may want to)

    // Openssl don't like to be inited several times so let's do it once and for all
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();

    for (unsigned i = 0; i < NB_ELEMS(initers); i++) {
        initers[i].init();
    }

    ext_rebind();
}
예제 #16
0
/**
 * Duplicate URI
 *
 * @v uri		URI
 * @ret uri		Duplicate URI
 *
 * Creates a modifiable copy of a URI.
 */
struct uri * uri_dup ( const struct uri *uri ) {
	struct uri *dup;
	size_t len;

	/* Allocate new URI */
	len = uri_copy_fields ( uri, NULL );
	dup = zalloc ( len );
	if ( ! dup )
		return NULL;
	ref_init ( &dup->refcnt, uri_free );

	/* Copy fields */
	uri_copy_fields ( uri, dup );

	/* Copy parameters */
	dup->params = params_get ( uri->params );

	DBGC ( uri, "URI duplicated" );
	uri_dump ( uri );
	DBGC ( uri, "\n" );

	return dup;
}
예제 #17
0
파일: ocsp.c 프로젝트: eworm-de/ipxe
/**
 * Create OCSP check
 *
 * @v cert		Certificate to check
 * @v issuer		Issuing certificate
 * @ret ocsp		OCSP check
 * @ret rc		Return status code
 */
int ocsp_check ( struct x509_certificate *cert,
		 struct x509_certificate *issuer,
		 struct ocsp_check **ocsp ) {
	int rc;

	/* Sanity checks */
	assert ( cert != NULL );
	assert ( issuer != NULL );
	assert ( x509_is_valid ( issuer ) );

	/* Allocate and initialise check */
	*ocsp = zalloc ( sizeof ( **ocsp ) );
	if ( ! *ocsp ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	ref_init ( &(*ocsp)->refcnt, ocsp_free );
	(*ocsp)->cert = x509_get ( cert );
	(*ocsp)->issuer = x509_get ( issuer );

	/* Build request */
	if ( ( rc = ocsp_request ( *ocsp ) ) != 0 )
		goto err_request;

	/* Build URI string */
	if ( ( rc = ocsp_uri_string ( *ocsp ) ) != 0 )
		goto err_uri_string;

	return 0;

 err_uri_string:
 err_request:
	ocsp_put ( *ocsp );
 err_alloc:
	*ocsp = NULL;
	return rc;
}
예제 #18
0
파일: pixbuf.c 프로젝트: 42wim/ipxe
/**
 * Allocate pixel buffer
 *
 * @v width		Width
 * @h height		Height
 * @ret pixbuf		Pixel buffer, or NULL on failure
 */
struct pixel_buffer * alloc_pixbuf ( unsigned int width, unsigned int height ) {
	struct pixel_buffer *pixbuf;

	/* Allocate and initialise structure */
	pixbuf = zalloc ( sizeof ( *pixbuf ) );
	if ( ! pixbuf )
		goto err_alloc_pixbuf;
	ref_init ( &pixbuf->refcnt, free_pixbuf );
	pixbuf->width = width;
	pixbuf->height = height;
	pixbuf->len = ( width * height * sizeof ( uint32_t ) );

	/* Allocate pixel data buffer */
	pixbuf->data = umalloc ( pixbuf->len );
	if ( ! pixbuf->data )
		goto err_alloc_data;

	return pixbuf;

 err_alloc_data:
	pixbuf_put ( pixbuf );
 err_alloc_pixbuf:
	return NULL;
}
예제 #19
0
파일: resolv.c 프로젝트: 42wim/ipxe
/**
 * Start name resolution
 *
 * @v resolv		Name resolution interface
 * @v name		Name to resolve
 * @v sa		Socket address to complete
 * @ret rc		Return status code
 */
int resolv ( struct interface *resolv, const char *name,
	     struct sockaddr *sa ) {
	struct resolv_mux *mux;
	size_t name_len = ( strlen ( name ) + 1 );
	int rc;

	/* Allocate and initialise structure */
	mux = zalloc ( sizeof ( *mux ) + name_len );
	if ( ! mux )
		return -ENOMEM;
	ref_init ( &mux->refcnt, NULL );
	intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt );
	intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt );
	mux->resolver = table_start ( RESOLVERS );
	if ( sa )
		memcpy ( &mux->sa, sa, sizeof ( mux->sa ) );
	memcpy ( mux->name, name, name_len );

	DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name );

	/* Start first resolver in chain.  There will always be at
	 * least one resolver (the numeric resolver), so no need to
	 * check for the zero-resolvers-available case.
	 */
	if ( ( rc = resmux_try ( mux ) ) != 0 )
		goto err;

	/* Attach parent interface, mortalise self, and return */
	intf_plug_plug ( &mux->parent, resolv );
	ref_put ( &mux->refcnt );
	return 0;

 err:
	ref_put ( &mux->refcnt );
	return rc;	
}
예제 #20
0
파일: rb_ogl3_uniform.c 프로젝트: vaplv/foo
static int
get_active_uniform
  (struct rb_context* ctxt,
   struct rb_program* program,
   GLuint index,
   GLsizei bufsize,
   GLchar* buffer,
   struct rb_uniform** out_uniform)
{
  struct rb_uniform* uniform = NULL;
  GLsizei uniform_namelen = 0;
  GLint uniform_size = 0;
  GLenum uniform_type;
  int err = 0;

  if(!ctxt
  || !program
  || !out_uniform
  || bufsize < 0
  || (bufsize && !buffer))
    goto error;

  OGL(GetActiveUniform
      (program->name,
       index,
       bufsize,
       &uniform_namelen,
       &uniform_size,
       &uniform_type,
       buffer));

  uniform = MEM_CALLOC(ctxt->allocator, 1, sizeof(struct rb_uniform));
  if(!uniform)
    goto error;
  ref_init(&uniform->ref);
  RB(context_ref_get(ctxt));
  uniform->ctxt = ctxt;
  RB(program_ref_get(program));
  uniform->program = program;
  uniform->index = index;
  uniform->type = uniform_type;
  uniform->set = get_uniform_setter(uniform_type);

  if(buffer) {
    /* Add 1 to namelen <=> include the null character. */
    ++uniform_namelen;

    uniform->name = MEM_ALLOC
      (ctxt->allocator, sizeof(char) * uniform_namelen);
    if(!uniform->name)
      goto error;

    uniform->name = strncpy(uniform->name, buffer, uniform_namelen);
    uniform->location = OGL(GetUniformLocation(program->name, uniform->name));
  }

exit:
  *out_uniform = uniform;
  return err;

error:
  if(uniform) {
    RB(uniform_ref_put(uniform));
    uniform = NULL;
  }
  err = -1;
  goto exit;
}
예제 #21
0
파일: dns.c 프로젝트: CSU-GH/gpxe
/**
 * Resolve name using DNS
 *
 * @v resolv		Name resolution interface
 * @v name		Name to resolve
 * @v sa		Socket address to fill in
 * @ret rc		Return status code
 */
static int dns_resolv ( struct resolv_interface *resolv,
			const char *name, struct sockaddr *sa ) {
	struct dns_request *dns;
	char *fqdn;
	int rc;

	/* Fail immediately if no DNS servers */
	if ( ! nameserver.st_family ) {
		DBG ( "DNS not attempting to resolve \"%s\": "
		      "no DNS servers\n", name );
		rc = -ENXIO;
		goto err_no_nameserver;
	}

	/* Ensure fully-qualified domain name if DHCP option was given */
	fqdn = dns_qualify_name ( name );
	if ( ! fqdn ) {
		rc = -ENOMEM;
		goto err_qualify_name;
	}

	/* Allocate DNS structure */
	dns = zalloc ( sizeof ( *dns ) );
	if ( ! dns ) {
		rc = -ENOMEM;
		goto err_alloc_dns;
	}
	ref_init ( &dns->refcnt, NULL );
	resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
	xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
	timer_init ( &dns->timer, dns_timer_expired );
	memcpy ( &dns->sa, sa, sizeof ( dns->sa ) );

	/* Create query */
	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
				       DNS_FLAG_RD );
	dns->query.dns.qdcount = htons ( 1 );
	dns->qinfo = ( void * ) dns_make_name ( fqdn, dns->query.payload );
	dns->qinfo->qtype = htons ( DNS_TYPE_A );
	dns->qinfo->qclass = htons ( DNS_CLASS_IN );

	/* Open UDP connection */
	if ( ( rc = xfer_open_socket ( &dns->socket, SOCK_DGRAM,
				       ( struct sockaddr * ) &nameserver,
				       NULL ) ) != 0 ) {
		DBGC ( dns, "DNS %p could not open socket: %s\n",
		       dns, strerror ( rc ) );
		goto err_open_socket;
	}

	/* Send first DNS packet */
	dns_send_packet ( dns );

	/* Attach parent interface, mortalise self, and return */
	resolv_plug_plug ( &dns->resolv, resolv );
	ref_put ( &dns->refcnt );
	free ( fqdn );
	return 0;	

 err_open_socket:
 err_alloc_dns:
	ref_put ( &dns->refcnt );
 err_qualify_name:
	free ( fqdn );
 err_no_nameserver:
	return rc;
}
예제 #22
0
/**
 * Parse URI
 *
 * @v uri_string	URI as a string
 * @ret uri		URI
 *
 * Splits a URI into its component parts.  The return URI structure is
 * dynamically allocated and must eventually be freed by calling
 * uri_put().
 */
struct uri * parse_uri ( const char *uri_string ) {
	struct uri *uri;
	struct parameters *params;
	char *raw;
	char *tmp;
	char *path;
	char *authority;
	size_t raw_len;
	unsigned int field;

	/* Allocate space for URI struct and a copy of the string */
	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
	uri = zalloc ( sizeof ( *uri ) + raw_len );
	if ( ! uri )
		return NULL;
	ref_init ( &uri->refcnt, uri_free );
	raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );

	/* Copy in the raw string */
	memcpy ( raw, uri_string, raw_len );

	/* Identify the parameter list, if present */
	if ( ( tmp = strstr ( raw, "##params" ) ) ) {
		*tmp = '\0';
		tmp += 8 /* "##params" */;
		params = find_parameters ( *tmp ? ( tmp + 1 ) : NULL );
		if ( params ) {
			uri->params = claim_parameters ( params );
		} else {
			/* Ignore non-existent submission blocks */
		}
	}

	/* Chop off the fragment, if it exists */
	if ( ( tmp = strchr ( raw, '#' ) ) ) {
		*(tmp++) = '\0';
		uri->fragment = tmp;
	}

	/* Identify absolute/relative URI */
	if ( ( tmp = strchr ( raw, ':' ) ) ) {
		/* Absolute URI: identify hierarchical/opaque */
		uri->scheme = raw;
		*(tmp++) = '\0';
		if ( *tmp == '/' ) {
			/* Absolute URI with hierarchical part */
			path = tmp;
		} else {
			/* Absolute URI with opaque part */
			uri->opaque = tmp;
			path = NULL;
		}
	} else {
		/* Relative URI */
		path = raw;
	}

	/* If we don't have a path (i.e. we have an absolute URI with
	 * an opaque portion, we're already finished processing
	 */
	if ( ! path )
		goto done;

	/* Chop off the query, if it exists */
	if ( ( tmp = strchr ( path, '?' ) ) ) {
		*(tmp++) = '\0';
		uri->query = tmp;
	}

	/* If we have no path remaining, then we're already finished
	 * processing.
	 */
	if ( ! path[0] )
		goto done;

	/* Identify net/absolute/relative path */
	if ( strncmp ( path, "//", 2 ) == 0 ) {
		/* Net path.  If this is terminated by the first '/'
		 * of an absolute path, then we have no space for a
		 * terminator after the authority field, so shuffle
		 * the authority down by one byte, overwriting one of
		 * the two slashes.
		 */
		authority = ( path + 2 );
		if ( ( tmp = strchr ( authority, '/' ) ) ) {
			/* Shuffle down */
			uri->path = tmp;
			memmove ( ( authority - 1 ), authority,
				  ( tmp - authority ) );
			authority--;
			*(--tmp) = '\0';
		}
	} else {
		/* Absolute/relative path */
		uri->path = path;
		authority = NULL;
	}

	/* If we don't have an authority (i.e. we have a non-net
	 * path), we're already finished processing
	 */
	if ( ! authority )
		goto done;

	/* Split authority into user[:password] and host[:port] portions */
	if ( ( tmp = strchr ( authority, '@' ) ) ) {
		/* Has user[:password] */
		*(tmp++) = '\0';
		uri->host = tmp;
		uri->user = authority;
		if ( ( tmp = strchr ( authority, ':' ) ) ) {
			/* Has password */
			*(tmp++) = '\0';
			uri->password = tmp;
		}
	} else {
		/* No user:password */
		uri->host = authority;
	}

	/* Split host into host[:port] */
	if ( ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) &&
	     ( tmp = strrchr ( uri->host, ':' ) ) ) {
		*(tmp++) = '\0';
		uri->port = tmp;
	}

	/* Decode fields in-place */
	for ( field = 0 ; field < URI_FIELDS ; field++ ) {
		if ( uri_field ( uri, field ) )
			uri_decode ( ( char * ) uri_field ( uri, field ) );
	}

 done:
	DBGC ( uri, "URI parsed \"%s\" to", uri_string );
	uri_dump ( uri );
	DBGC ( uri, "\n" );

	return uri;
}
예제 #23
0
파일: dcl2.c 프로젝트: setekhid/cfront1
void stmt.dcl()
/*
	typecheck statement "this" in scope "curr_block->tbl"
*/
{
	Pstmt ss;
	Pname n;
	Pname nn;
	Pstmt ostmt = Cstmt;

	for (ss=this; ss; ss=ss->s_list) {
		Pstmt old_loop, old_switch;
		Cstmt = ss;
		Ptable tbl = curr_block->memtbl;
/*error('d',"ss %d%k tbl %d e %d%k s %d%k sl %d%k", ss, ss->base, tbl, ss->e, (ss->e)?ss->e->base:0, ss->s, (ss->s)?ss->s->base:0, ss->s_list, (ss->s_list)?ss->s_list->base:0);*/
		switch (ss->base) {
		case BREAK:
			if (curr_loop==0 && curr_switch==0)
				error("%k not in loop or switch",BREAK);
			ss->reached();
			break;

		case CONTINUE:
			if (curr_loop == 0) error("%k not in loop",CONTINUE);
			ss->reached();
			break;

		case DEFAULT:
			if (curr_switch == 0) {
				error("default not in switch");
				break;
			}
			if (curr_switch->has_default) error("two defaults in switch");
			curr_switch->has_default = ss;
			ss->s->s_list = ss->s_list;
			ss->s_list = 0;
			ss->s->dcl();
			break;

		case SM:
			switch (ss->e->base) {
			case DUMMY:
				ss->e = 0;
				break;
					// check for unused results
					// don't check operators that are likely
					// to be overloaded to represent "actions":
					// ! ~ < <= > >= << >>
			case EQ:
			case NE:
			case PLUS:
			case MINUS:
			case REF:
			case DOT:
			case MUL:
			case DIV:
			case ADDROF:
			case AND:
			case OR:
			case ER:
			case DEREF:
			case ANDAND:
			case OROR:
			case NAME:
				if (ss->e->tp) break;	// avoid looking at generated code
				ss->e = ss->e->typ(tbl);
				if (ss->e->tp->base != VOID) error('w',"result of%kE not used",ss->e->base);
				break;
			default:
				ss->e = ss->e->typ(tbl);
			}
		//	ss->e = (ss->e != dummy) ? ss->e->typ(tbl) : 0;
			break;

		case RETURN:
		{	Pname fn = cc->nof;
			Ptype rt = Pfct(fn->tp)->returns;
			Pexpr v = ss->e;
			if (v != dummy) {
				if (rt->base == VOID) {
					error('w',"unX return value");
					/*refuse to return the value:*/
					ss->e = dummy;
				}
				else {
					v = v->typ(tbl);
				lx:
//error('d',"return %t",rt);
					switch (rt->base) {
					case TYPE:
						rt = Pbase(rt)->b_name->tp;
						goto lx;
					case RPTR:
						ss->e = ref_init(Pptr(rt),v,tbl);
						if (v->lval(0)==0
						&& v->tp->tconst()==0)
							error('w',"reference to non-lvalue returned");
						else if (v->base==NAME
						&& Pname(v)->n_scope==FCT)
							error('w',"reference to local variable returned");
								
							
						break;
					case COBJ:
					{	Pname rv = tbl->look("_result",0);
						ss->e = class_init(rv,rt,v,tbl);
//error('d',"ss->e %t %d",ss->e->tp,ss->e->base);
						break;
					}
					case ANY:
						break;
					case INT:
					case CHAR:
					case LONG:
					case SHORT:
						if (Pbase(rt)->b_unsigned
						&& v->base==UMINUS
						&& v->e2->base==ICON)
							error('w',"negative retured fromF returning unsigned");
					default:
		{	Pname cn;
			int i;
			if ((cn=v->tp->is_cl_obj())
			&& (i=can_coerce(rt,v->tp))
			&& Ncoerce) {
				if (1 < i) error("%d possible conversions for return value",i);
				Pclass cl = (Pclass)cn->tp;
				Pref r = new ref(DOT,v,Ncoerce);
				Pexpr c = new expr(G_CALL,r,0);
				c->fct_name = Ncoerce;
				c->tp = rt;
				ss->e = c;
				break;
			}
		}
						ss->e = v;
						if (rt->check(v->tp,ASSIGN))
							error("bad return valueT for%n:%t (%tX)",fn,v->tp,rt);
					}
				}
			}
			else {
				if (rt->base != VOID) error('w',"return valueX");
			}
			ss->reached();
			break;
		}

		case DO:	/* in DO the stmt is before the test */					inline_restr |= 8;
			old_loop = curr_loop;
			curr_loop = ss;
			if (ss->s->base == DCL) error('s',"D as onlyS in do-loop");
			ss->s->dcl();
		/*	tbl = curr_block->memtbl;*/
			ss->e = ss->e->typ(tbl);
			ss->e = check_cond(ss->e,DO,tbl);
			curr_loop = old_loop;
			break;

		case WHILE:
			inline_restr |= 8;
			old_loop = curr_loop;
			curr_loop = ss;
			ss->e = ss->e->typ(tbl);
			/*ss->e->tp->num_ptr(ss->base);*/
			ss->e = check_cond(ss->e,WHILE,tbl);
			if (ss->s->base == DCL) error('s',"D as onlyS in while-loop");
			ss->s->dcl();
			curr_loop = old_loop;
			break;

		case SWITCH:
		{	int ne = 0;
			inline_restr |= 4;
			old_switch = curr_switch;
			curr_switch = ss;
			ss->e = ss->e->typ(tbl);
		/*	ss->e->tp->num_ptr(SWITCH);*/
			ss->e = check_cond(ss->e,SWITCH,tbl);
			{	Ptype tt = ss->e->tp;
			sii:
				switch (tt->base) {
				case TYPE:
					tt = ((Pbase)tt)->b_name->tp; goto sii;
				case EOBJ:
					ne = Penum(Pbase(tt)->b_name->tp)->no_of_enumerators;
				case ZTYPE:
				case ANY:
				case CHAR:
				case SHORT:
				case INT:
				case LONG:
				case FIELD:
					break;
				default:
					error('s',"%t switchE",ss->e->tp);
				}
			}
			ss->s->dcl();
			if (ne) {	/* see if the number of cases is "close to"
					   but not equal to the number of enumerators
					*/
				int i = 0;
				Pstmt cs;
				for (cs=ss->case_list; cs; cs=cs->case_list) i++;
				if (i && i!=ne) {
					if (ne < i) {
				ee:		error('w',"switch (%t) with %d cases (%d enumerators)",ss->e->tp,i,ne);
					}
					else {
						switch (ne-i) {
						case 1: if (3<ne) goto ee;
						case 2: if (7<ne) goto ee;
						case 3: if (23<ne) goto ee;
						case 4: if (60<ne) goto ee;
						case 5: if (99<ne) goto ee;
						}
					}
				}
			}
			curr_switch = old_switch;
			break;
		}
		case CASE:
			if (curr_switch == 0) {
				error("case not in switch");
				break;
			}
			ss->e = ss->e->typ(tbl);
			ss->e->tp->num_ptr(CASE);
			{	Ptype tt = ss->e->tp;
			iii:
				switch (tt->base) {
				case TYPE:
					tt = Pbase(tt)->b_name->tp; goto iii;
				case ZTYPE:
				case ANY:
				case CHAR:
				case SHORT:
				case INT:
				case LONG:
					break;
				default:
					error('s',"%t caseE",ss->e->tp);
				}
			}
			if (1) {
				Neval = 0;
				int i = ss->e->eval();
				if (Neval == 0) {
					Pstmt cs;
					for (cs=curr_switch->case_list; cs; cs=cs->case_list) {
						if (cs->case_value == i) error("case %d used twice in switch",i);
					}
					ss->case_value = i;
					ss->case_list = curr_switch->case_list;
					curr_switch->case_list = ss;
				}
				else
					error("bad case label: %s",Neval);
			}
			if (ss->s->s_list) error('i',"case%k",ss->s->s_list->base);
			ss->s->s_list = ss->s_list;
			ss->s_list = 0;
			ss->s->dcl();
			break;

		case GOTO:
			inline_restr |= 2;
			ss->reached();
		case LABEL:
			/* Insert label in function mem table;
			   labels have function scope.
			*/
			n = ss->d;
			nn = cc->ftbl->insert(n,LABEL);

			/* Set a ptr to the mem table corresponding to the scope
			   in which the label actually occurred.  This allows the
			   processing of goto's in the presence of ctors and dtors
			*/
			if(ss->base == LABEL) {
				nn->n_realscope = curr_block->memtbl;
				inline_restr |= 1;
			}

			if (Nold) {
				if (ss->base == LABEL) {
					if (nn->n_initializer) error("twoDs of label%n",n);
					nn->n_initializer = (Pexpr)1;
				}
				if (n != nn) ss->d = nn;
			}
			else {
				if (ss->base == LABEL) nn->n_initializer = (Pexpr)1;
				nn->where = ss->where;
			}
			if (ss->base == GOTO)
				nn->use();
			else {
				if (ss->s->s_list) error('i',"label%k",ss->s->s_list->base);
				ss->s->s_list = ss->s_list;
				ss->s_list = 0;
				nn->assign();
			}
			if (ss->s) ss->s->dcl();
			break;

		case IF:
		{	Pexpr ee = ss->e->typ(tbl);
			if (ee->base == ASSIGN) {
				Neval = 0;
				(void)ee->e2->eval();
				if (Neval == 0)
					error('w',"constant assignment in condition");
			}
			ss->e = ee = check_cond(ee,IF,tbl);
//error('d',"if (%t)",ee->tp);
			switch (ee->tp->base) {
			case INT:
			case ZTYPE:
			{	int i;
				Neval = 0;
				i = ee->eval();
//error('d',"if (int:%k) => (i %s)",ss->e->base,i,Neval?Neval:"0");
				if (Neval == 0) {
					Pstmt sl = ss->s_list;
					if (i) {
						DEL(ss->else_stmt);
						ss->s->dcl();
						*ss = *ss->s;
					}
					else {
						DEL(ss->s);
						if (ss->else_stmt) {
							ss->else_stmt->dcl();
							*ss = *ss->else_stmt;
						}
						else {
							ss->base = SM;
							ss->e = dummy;
							ss->s = 0;
						}
					}
					ss->s_list = sl;
					continue;
				}
			}
			}
			ss->s->dcl();
			if (ss->else_stmt) ss->else_stmt->dcl();
			break;
		}
		case FOR:
			inline_restr |= 8;
			old_loop = curr_loop;
			curr_loop = ss;
			if (ss->for_init) {
				Pstmt fi = ss->for_init;
				switch (fi->base) {
				case SM:
					if (fi->e == dummy) {
						ss->for_init = 0;
						break;
					}
				default:
					fi->dcl();
					break;
				case DCL:
					fi->dcl();
//error('d',"dcl=>%k %d",fi->base,fi->base);
					switch (fi->base) {
					case BLOCK:
					{
					/* { ... for( { a } b ; c) d ; e }
						=>
					   { ... { a for ( ; b ; c) d ; e }}
					*/
						Pstmt tmp = new stmt (SM,curloc,0);
						*tmp = *ss;	/* tmp = for */
						tmp->for_init = 0;
						*ss = *fi;	/* ss = { } */
						if (ss->s)
							ss->s->s_list = tmp;
						else
							ss->s = tmp;
						curr_block = (Pblock)ss;
						tbl = curr_block->memtbl;
						ss = tmp;	/* rest of for and s_list */
						break;
					}
					}
				}
			}
			if (ss->e == dummy)
				ss->e = 0;
			else {
				ss->e = ss->e->typ(tbl);
				ss->e = check_cond(ss->e,FOR,tbl);
			}
			if (ss->s->base == DCL) error('s',"D as onlyS in for-loop");
			ss->s->dcl();
			ss->e2 = (ss->e2 == dummy) ? 0 : ss->e2->typ(tbl);
			curr_loop = old_loop;
			break;

		case DCL:	/* declaration after statement */
		{
			/*	collect all the contiguous DCL nodes from the
				head of the s_list. find the next statement
			*/
			int non_trivial = 0;
			int count = 0;
			Pname tail = ss->d;
			for (Pname nn=tail; nn; nn=nn->n_list) {
				//	find tail;
				//	detect non-trivial declarations
				count++;
//error('d',"dcl:%n list %d stc %d in %d",nn,nn->n_list,nn->n_sto,nn->n_initializer);
				if (nn->n_list) tail = nn->n_list;
				Pname n = tbl->look(nn->string,0);
				if (n && n->n_table==tbl) non_trivial = 2;
				if (non_trivial == 2) continue;
				if (nn->n_sto==STATIC || nn->tp->is_ref()) {
					non_trivial = 2;
					continue;
				}
				Pexpr in = nn->n_initializer;
				if (in)
					switch (in->base) {
					case ILIST:
					case STRING:
						non_trivial = 2;
						continue;
					default:
						non_trivial = 1;
					}
				Pname cln = nn->tp->is_cl_obj();
				if (cln == 0) cln = cl_obj_vec;
				if (cln == 0) continue;
				if (Pclass(cln->tp)->has_dtor()) non_trivial = 2;
				if (Pclass(cln->tp)->has_ctor()) non_trivial = 2;
			}
//error('d',"non_trivial %d",non_trivial);
			while( ss->s_list && ss->s_list->base==DCL ) {
				Pstmt sx = ss->s_list;
				tail = tail->n_list = sx->d;	// add to tail
				for (nn=sx->d; nn; nn=nn->n_list) {
					//	find tail;
					//	detect non-trivial declarations
					count++;
					if (nn->n_list) tail = nn->n_list;
					Pname n = tbl->look(nn->string,0);
					if (n && n->n_table==tbl) non_trivial = 2;
					if (non_trivial == 2) continue;
					if (nn->n_sto==STATIC || nn->tp->is_ref()) {
						non_trivial = 2;
						continue;
					}
					Pexpr in = nn->n_initializer;
					if (in)
						switch (in->base) {
						case ILIST:
						case STRING:
							non_trivial = 2;
							continue;
						}
					non_trivial = 1;
					Pname cln = nn->tp->is_cl_obj();
					if (cln == 0) cln = cl_obj_vec;
					if (cln == 0) continue;
					if (Pclass(cln->tp)->has_ctor()) non_trivial = 2;
					if (Pclass(cln->tp)->has_dtor()) non_trivial = 2;
				}
				ss->s_list = sx->s_list;
			/*	delete sx;	*/
			}
			Pstmt next_st = ss->s_list;
//error('d',"non_trivial %d curr_block->own_tbl %d inline_restr %d",non_trivial,curr_block->own_tbl,inline_restr);
			if (non_trivial==2	/* must */
			|| (non_trivial==1	/* might */
				&& ( curr_block->own_tbl==0	/* just as well */
				|| inline_restr&3		/* label seen */)
			  	)
			) {
				/*	Create a new block,
					put all the declarations at the head,
					and the remainder of the slist as the
					statement list of the block.
				*/
				ss->base = BLOCK;

				/*	check that there are no redefinitions since the last
					"real" (user-written, non-generated) block
				*/
				for( nn=ss->d; nn; nn=nn->n_list ) {
					Pname n;
					if( curr_block->own_tbl
					&&  (n=curr_block->memtbl->look(nn->string,0))
					&&  n->n_table->real_block==curr_block->memtbl->real_block)
						error("twoDs of%n",n);
				}

				/*	attach the remainder of the s_list
					as the statement part of the block.
				*/
				ss->s = next_st;
				ss->s_list = 0;

				/*	create the table in advance, in order to set the
					real_block ptr to that of the enclosing table
				*/
				ss->memtbl = new table(count+4,tbl,0);
				ss->memtbl->real_block = curr_block->memtbl->real_block;

				Pblock(ss)->dcl(ss->memtbl);
			}
			else {	/*	to reduce the number of symbol tables,
					do not make a new block,
					instead insert names in enclosing block,
					and make the initializers into expression
					statements.
				*/
				Pstmt sss = ss;
				for( nn=ss->d; nn; nn=nn->n_list ) {
					Pname n = nn->dcl(tbl,FCT);
//error('d',"%n->dcl(%d) -> %d init %d sss=%d ss=%d",nn,tbl,n,n->n_initializer,sss,ss);
					if (n == 0) continue;
					Pexpr in = n->n_initializer;
					n->n_initializer = 0;
					if (ss) {
						sss->base = SM;
						ss = 0;
					}
					else
						sss = sss->s_list = new estmt(SM,sss->where,0,0);
					if (in) {
						switch (in->base) {
						case G_CALL:	/* constructor? */
						{
							Pname fn = in->fct_name;
							if (fn && fn->n_oper==CTOR) break;
						}
						default:
							in = new expr(ASSIGN,n,in);
						}
						sss->e = in->typ(tbl);
					}
					else
						sss->e = dummy;
				}
				ss = sss;
				ss->s_list = next_st;
			}
			break;
		}

		case BLOCK:
			Pblock(ss)->dcl(tbl);
			break;

		case ASM:
			/* save string */
			break;

		default:
			error('i',"badS(%d %d)",ss,ss->base);
		}
	}

	Cstmt = ostmt;
}