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; }
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; }
/******************************************************************************* * * 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; }
/** * 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; }
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; }
/******************************************************************************* * * 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; }
_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; }
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; }
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; }
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; }
/** * 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; }
/******************************************************************************* * * 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; }
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; }
/******************************************************************************* * * 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; }
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(); }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
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; }
/** * 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; }
/** * 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; }
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; }