/* Add the playlist item to the requested node and fire a notification */ static void AddItem( playlist_t *p_playlist, playlist_item_t *p_item, playlist_item_t *p_node, int i_mode, int i_pos ) { PL_ASSERT_LOCKED; ARRAY_APPEND(p_playlist->items, p_item); ARRAY_APPEND(p_playlist->all_items, p_item); if( i_pos == PLAYLIST_END ) playlist_NodeAppend( p_playlist, p_item, p_node ); else playlist_NodeInsert( p_playlist, p_item, p_node, i_pos ); playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id, !( i_mode & PLAYLIST_NO_REBUILD ) ); }
struct args *new_args(struct expr *e) { struct args *aa = malloc(sizeof(struct args)); INIT_ARRAY(aa->v, 4); ARRAY_APPEND(aa->v, e); return aa; }
static int ListScripts( addons_finder_t *p_finder, addon_type_t type ) { char *psz_dir = getAddonInstallDir( type ); if ( ! psz_dir ) return VLC_EGENERIC; char **ppsz_list = NULL; int i_count = vlc_scandir( psz_dir, &ppsz_list, ListScript_filter, NULL ); for ( int i=0; i< i_count; i++ ) { char *psz_file = ppsz_list[i]; if( !psz_file ) break; if ( FileBelongsToManagedAddon( p_finder, type, psz_file ) ) continue; addon_entry_t *p_entry = addon_entry_New(); p_entry->e_state = ADDON_INSTALLED; p_entry->e_type = type; p_entry->e_flags |= ADDON_BROKEN; p_entry->psz_name = strdup(psz_file); p_entry->psz_description = strdup("Lua script"); ARRAY_APPEND( p_finder->entries, p_entry ); free( psz_file ); } free( ppsz_list ); free( psz_dir ); return VLC_SUCCESS; }
/***************************************************************************** * Check if another part exists and import it *****************************************************************************/ static bool ImportNextFile( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; char *psz_path = GetFilePath( p_access, FILE_COUNT ); if( !psz_path ) return false; struct stat st; if( vlc_stat( psz_path, &st ) ) { msg_Dbg( p_access, "could not stat %s: %s", psz_path, vlc_strerror_c(errno) ); free( psz_path ); return false; } if( !S_ISREG( st.st_mode ) ) { msg_Dbg( p_access, "%s is not a regular file", psz_path ); free( psz_path ); return false; } msg_Dbg( p_access, "%s exists", psz_path ); free( psz_path ); ARRAY_APPEND( p_sys->file_sizes, st.st_size ); p_sys->size += st.st_size; return true; }
/** * Create a playlist node * * \param p_playlist the playlist * \param psz_name the name of the node * \param p_parent the parent node to attach to or NULL if no attach * \param i_pos position of the node in the parent, PLAYLIST_END to append to end. * \param p_flags miscellaneous flags * \param p_input the input_item to attach to or NULL if it has to be created * \return the new node */ playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, const char *psz_name, playlist_item_t *p_parent, int i_pos, int i_flags, input_item_t *p_input ) { input_item_t *p_new_input = NULL; playlist_item_t *p_item; PL_ASSERT_LOCKED; if( !psz_name ) psz_name = _("Undefined"); if( !p_input ) p_new_input = input_item_NewWithType( NULL, psz_name, 0, NULL, 0, -1, ITEM_TYPE_NODE ); p_item = playlist_ItemNewFromInput( p_playlist, p_input ? p_input : p_new_input ); if( p_new_input ) vlc_gc_decref( p_new_input ); if( p_item == NULL ) return NULL; p_item->i_children = 0; ARRAY_APPEND(p_playlist->all_items, p_item); if( p_parent != NULL ) playlist_NodeInsert( p_playlist, p_item, p_parent, i_pos == PLAYLIST_END ? -1 : i_pos ); playlist_SendAddNotify( p_playlist, p_item->i_id, p_parent ? p_parent->i_id : -1, !( i_flags & PLAYLIST_NO_REBUILD )); p_item->i_flags |= i_flags; return p_item; }
struct stmts *new_stmts(struct stmt *s) { struct stmts *ss = malloc(sizeof(struct stmts)); INIT_ARRAY(ss->v, 4); ARRAY_APPEND(ss->v, s); return ss; }
static void print_commit (FILE * out, const database_t * db, changeset_t * cs, cvs_connection_t * s) { version_t * v = cs->versions[0]; version_t ** fetch = NULL; version_t ** fetch_end = NULL; // Get the list of versions to fetch. for (version_t ** i = cs->versions; i != cs->versions_end; ++i) { if (!(*i)->used) continue; version_t * cv = version_live (*i); if (cv != NULL && cv->mark == SIZE_MAX) ARRAY_APPEND (fetch, cv); } fprintf (stderr, "%s COMMIT", format_date (&cs->time, false)); // Get the versions. grab_versions (out, db, s, fetch, fetch_end); xfree (fetch); v->branch->last = cs; cs->mark = ++mark_counter; v->branch->changeset.mark = cs->mark; fprintf (out, "commit %s/%s\n", branch_prefix, *v->branch->tag ? v->branch->tag : master); fprintf (out, "mark :%zu\n", cs->mark); fprintf (out, "committer %s <%s> %ld +0000\n", v->author, v->author, cs->time); fprintf (out, "data %zu\n%s\n", strlen (v->log), v->log); for (changeset_t ** i = cs->merge; i != cs->merge_end; ++i) if ((*i)->mark == 0) fprintf (stderr, "Whoops, out of order!\n"); else if ((*i)->mark == mark_counter) fprintf (stderr, "Whoops, self-ref\n"); else fprintf (out, "merge :%zu\n", (*i)->mark); const char * last_path = NULL; for (version_t ** i = cs->versions; i != cs->versions_end; ++i) if ((*i)->used) { version_t * vv = version_normalise (*i); if (vv->dead) fprintf (out, "D %s\n", vv->file->path); else fprintf (out, "M %s :%zu %s\n", vv->exec ? "755" : "644", vv->mark, vv->file->path); last_path = output_entries_list ( out, db, v->branch->branch_versions, vv->file, last_path); } fprintf (stderr, "\n"); }
changeset_t * database_new_changeset (database_t * db) { changeset_t * result = xmalloc (sizeof (changeset_t)); changeset_init (result); ARRAY_APPEND (db->changesets, result); return result; }
void sym_map_for_each( struct SymMap *sym_map, void (*callback)(char*, struct SymMapNode*, void*), void *data) { struct CharArray current_symbol = { NULL, 0, 0 }; ARRAY_APPEND(current_symbol, '\0'); sym_map_for_each_rec(&sym_map->root, callback, data, ¤t_symbol); ARRAY_FREE(current_symbol); }
static void sym_map_for_each_rec( struct SymMapNode *node, void (*callback)(char*, struct SymMapNode*, void*), void *data, struct CharArray *current_symbol) { /* 0. Overview: * This function traverses the symbol map trie recursively * calling the callback function for every occurence of a value attached * in a given point in the trie. */ int i, count; struct SymMapNode *child; /* 1. Check for the callback condition */ if (node->is_set) { callback(current_symbol->data, node, data); } /* 2. Traverse the deeper nodes recursively */ count = node->children.size; child = node->children.data; for (i = 0; i < count; ++i) { /* 2.1. Append the current character */ ARRAY_POP(*current_symbol); ARRAY_APPEND(*current_symbol, child->key); ARRAY_APPEND(*current_symbol, '\0'); /* 2.2. Make the recursive call */ sym_map_for_each_rec(child, callback, data, current_symbol); /* 2.3. Remove the last appended character */ ARRAY_POP(*current_symbol); ARRAY_POP(*current_symbol); ARRAY_APPEND(*current_symbol, '\0'); /* 2.4. Advance the current child pointer */ ++child; } }
static void TwalkGetNames(const void *data, const VISIT which, const int depth) { if (which != postorder && which != leaf) return; (void) depth; const variable_t *var = *(const variable_t **)data; DECL_ARRAY(char *) *names = twalk_ctx; char *dup = strdup(var->psz_name); if (dup != NULL) ARRAY_APPEND(*names, dup); }
// Release all the child tags of a branch. static void tag_released (heap_t * heap, tag_t * tag, tag_t *** tree_order, tag_t *** tree_order_end) { ARRAY_APPEND (*tree_order, tag); tag->rank = 0; for (parent_branch_t * i = tag->parents; i != tag->parents_end; ++i) if (i->branch->rank >= tag->rank) tag->rank = i->branch->rank + 1; for (branch_tag_t * i = tag->tags; i != tag->tags_end; ++i) { assert (i->tag->changeset.unready_count != 0); if (--i->tag->changeset.unready_count == 0) { i->tag->is_released = true; heap_insert (heap, i->tag); } } }
/** * Release an item * * \param p_item item to delete * \return VLC_SUCCESS */ int playlist_ItemRelease( playlist_item_t *p_item ) { /* For the assert */ playlist_t *p_playlist = p_item->p_playlist; PL_ASSERT_LOCKED; /* Surprise, we can't actually do more because we * don't do refcounting, or eauivalent. * Because item are not only accessed by their id * using playlist_item outside the PL_LOCK isn't safe. * Most of the modules does that. * * Who wants to add proper memory management? */ uninstall_input_item_observer( p_item ); ARRAY_APPEND( pl_priv(p_playlist)->items_to_delete, p_item); return VLC_SUCCESS; }
void sym_map_insert( struct SymMap *sym_map, char *key, VAL_LOC_T stack_loc) { struct SymMapNode *node = &sym_map->root; char *current = key; LOG_TRACE( "sym_map_insert(%s, %td, {%d, %d})", key, stack_loc, source_loc.line, source_loc.column); while (*current) { int i; bool found = false; for (i = 0; i < node->children.size; ++i) { if (node->children.data[i].key == *current) { node = node->children.data + i; found = true; break; } } if (!found) { struct SymMapNode new_node = { 0, { NULL, 0, 0 }, false, 0 }; new_node.key = *current; ARRAY_APPEND(node->children, new_node); node = node->children.data + i; } ++current; } if (node->is_set) { char *string = sym_map_serialize(sym_map); LOG_ERROR("Symbol map at error point:\n%s", string); mem_free(string); err_push("RUNTIME", "Symbol \"%s\" already inserted", key); } else { node->is_set = true; node->stack_loc = stack_loc; } }
static void ResetCurrentlyPlaying( playlist_t *p_playlist, playlist_item_t *p_cur ) { playlist_private_t *p_sys = pl_priv(p_playlist); stats_TimerStart( p_playlist, "Items array build", STATS_TIMER_PLAYLIST_BUILD ); PL_DEBUG( "rebuilding array of current - root %s", PLI_NAME( p_sys->status.p_node ) ); ARRAY_RESET( p_playlist->current ); p_playlist->i_current_index = -1; for( playlist_item_t *p_next = NULL; ; ) { /** FIXME: this is *slow* */ p_next = playlist_GetNextLeaf( p_playlist, p_sys->status.p_node, p_next, true, false ); if( !p_next ) break; if( p_next == p_cur ) p_playlist->i_current_index = p_playlist->current.i_size; ARRAY_APPEND( p_playlist->current, p_next); } PL_DEBUG("rebuild done - %i items, index %i", p_playlist->current.i_size, p_playlist->i_current_index); if( var_GetBool( p_playlist, "random" ) && ( p_playlist->current.i_size > 0 ) ) { /* Shuffle the array */ for( unsigned j = p_playlist->current.i_size - 1; j > 0; j-- ) { unsigned i = vlc_lrand48() % (j+1); /* between 0 and j */ playlist_item_t *p_tmp; /* swap the two items */ p_tmp = ARRAY_VAL(p_playlist->current, i); ARRAY_VAL(p_playlist->current,i) = ARRAY_VAL(p_playlist->current,j); ARRAY_VAL(p_playlist->current,j) = p_tmp; } } p_sys->b_reset_currently_playing = false; stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_BUILD ); }
/** * Add a callback for an event. */ int vlc_event_attach( vlc_event_manager_t * p_em, vlc_event_type_t event_type, vlc_event_callback_t pf_callback, void *p_user_data ) { vlc_event_listener_t * listener; vlc_event_listeners_group_t *slot = &p_em->events[event_type]; listener = malloc(sizeof(vlc_event_listener_t)); if( !listener ) return VLC_ENOMEM; listener->p_user_data = p_user_data; listener->pf_callback = pf_callback; vlc_mutex_lock( &p_em->lock ); ARRAY_APPEND( slot->listeners, listener ); vlc_mutex_unlock( &p_em->lock ); return VLC_SUCCESS; }
/* * Load a file into a buffer allocated with malloc. Must be freed by caller. * The filename may be "-" to read from stdin. */ static char *read_file(const char *filename) { FILE *fp = stdin; ARRAY_DECL(char, buffer); size_t nr; int err; char nulchar = '\0'; if (strcmp(filename, "-") != 0) { fp = fopen(filename, "r"); if (fp == NULL) system_error(filename); } ARRAY_ALLOC(buffer, 8); do { /* Grow the buffer if needed. */ if (buffer_size >= buffer_mem) ARRAY_GROW(buffer); nr = fread(buffer + buffer_size, 1, buffer_mem - buffer_size, fp); buffer_size += nr; } while (nr > 0); /* TODO: It sucks a bit to need a variable nulchar for this. */ ARRAY_APPEND(buffer, nulchar); if (ferror(fp)) system_error("fread"); if (strcmp(filename, "-") != 0) { err = fclose(fp); if (err == -1) system_error("fclose"); } return buffer; }
static void filter_input (database_t * db, FILE * in) { size_t n = 0; char * line = NULL; ssize_t len; while ((len = getline (&line, &n, in)) >= 0) { if (len > 0 && line[len - 1] == '\n') line[--len] = 0; if (len == 0) continue; if (strlen (line) != (size_t) len) fatal ("Line with NUL from filter\n"); if (starts_with (line, "DELETE TAG ")) { tag_t * tag = database_find_tag (db, line + 11); if (tag == NULL) fatal ("Unknown tag from filter: %s\n", line); if (tag->branch_versions != NULL) fatal ("Filter attempts to delete branch: %s\n", line); tag->deleted = true; } else if (starts_with (line, "MERGE ")) { char * ref1 = line + 6; char * ref2 = strchr (ref1, ' '); if (ref2 == NULL) fatal ("Illegal merge from filter: '%s'\n", line); *ref2++ = 0; changeset_t * cs1 = ref_lookup (db, ref1); changeset_t * cs2 = ref_lookup (db, ref2); if (cs2->type == ct_tag) as_tag (cs2)->merge_source = true; ARRAY_APPEND (cs1->merge, cs2); } else fatal ("Unknown line from filter: '%s'\n", line); } xfree (line); }
static int ParseManifest( addons_finder_t *p_finder, addon_entry_t *p_entry, const char *psz_tempfile, stream_t *p_stream ) { int i_num_entries_created = 0; const char *p_node; int i_current_node_type; /* attr */ const char *attr, *value; /* temp reading */ const char *psz_filename = NULL; int i_filetype = -1; xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream ); if( !p_xml_reader ) return 0; if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM ) { msg_Err( p_finder, "invalid xml file" ); goto end; } if ( strcmp( p_node, "videolan") ) { msg_Err( p_finder, "unsupported XML data format" ); goto end; } while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 ) { switch( i_current_node_type ) { case XML_READER_STARTELEM: { BINDNODE("resource", psz_filename, TYPE_STRING) data_pointer.e_type = TYPE_NONE; /* * Manifests are not allowed to update addons properties * such as uuid, score, downloads, ... * On the other hand, repo API must not set files directly. */ if ( ! strcmp( p_node, "resource" ) ) { while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if ( !strcmp( attr, "type" ) ) { i_filetype = ReadType( value ); } } } else if ( ! strcmp( p_node, "addon" ) ) { while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if ( !strcmp( attr, "type" ) ) { p_entry->e_type = ReadType( value ); } } } break; } case XML_READER_TEXT: if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break; if ( data_pointer.e_type == TYPE_STRING ) *data_pointer.u_data.ppsz = strdup( p_node ); else if ( data_pointer.e_type == TYPE_LONG ) *data_pointer.u_data.pl = atol( p_node ); else if ( data_pointer.e_type == TYPE_INTEGER ) *data_pointer.u_data.pi = atoi( p_node ); break; case XML_READER_ENDELEM: if ( ! strcmp( p_node, "resource" ) ) { if ( psz_filename && i_filetype >= 0 ) { addon_file_t *p_file = malloc( sizeof(addon_file_t) ); p_file->e_filetype = i_filetype; p_file->psz_filename = strdup( psz_filename ); if ( asprintf( & p_file->psz_download_uri, "unzip://%s!/%s", psz_tempfile, psz_filename ) > 0 ) { ARRAY_APPEND( p_entry->files, p_file ); msg_Dbg( p_finder, "manifest lists file %s extractable from %s", psz_filename, p_file->psz_download_uri ); i_num_entries_created++; } else { free( p_file->psz_filename ); free( p_file ); } } /* reset temp */ psz_filename = NULL; i_filetype = -1; } data_pointer.e_type = TYPE_NONE; break; default: break; } } end: xml_ReaderDelete( p_xml_reader ); return i_num_entries_created; }
static int ParseCategoriesInfo( addons_finder_t *p_finder, stream_t *p_stream ) { int i_num_entries_created = 0; const char *p_node; const char *attr, *value; int i_current_node_type; addon_entry_t *p_entry = NULL; xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream ); if( !p_xml_reader ) return 0; if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM ) { msg_Err( p_finder, "invalid xml file" ); goto end; } if ( strcmp( p_node, "videolan") ) { msg_Err( p_finder, "unsupported XML data format" ); goto end; } while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 ) { switch( i_current_node_type ) { case XML_READER_STARTELEM: { if ( ! strcmp( p_node, "addon" ) ) { if ( p_entry ) /* Unclosed tag */ addon_entry_Release( p_entry ); p_entry = addon_entry_New(); p_entry->psz_source_module = strdup( ADDONS_MODULE_SHORTCUT ); p_entry->e_flags = ADDON_MANAGEABLE; p_entry->e_state = ADDON_NOTINSTALLED; while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if ( !strcmp( attr, "type" ) ) { p_entry->e_type = ReadType( value ); } else if ( !strcmp( attr, "id" ) ) { addons_uuid_read( value, & p_entry->uuid ); } else if ( !strcmp( attr, "downloads" ) ) { p_entry->i_downloads = atoi( value ); } else if ( !strcmp( attr, "score" ) ) { p_entry->i_score = atol( value ); } else if ( !strcmp( attr, "version" ) ) { p_entry->psz_version = strdup( value ); } } break; } if ( !p_entry ) break; BINDNODE("name", p_entry->psz_name, TYPE_STRING) BINDNODE("archive", p_entry->psz_archive_uri, TYPE_STRING) BINDNODE("summary", p_entry->psz_summary, TYPE_STRING) BINDNODE("description", p_entry->psz_description, TYPE_STRING) BINDNODE("image", p_entry->psz_image_data, TYPE_STRING) BINDNODE("creator", p_entry->psz_author, TYPE_STRING) BINDNODE("sourceurl", p_entry->psz_source_uri, TYPE_STRING) data_pointer.e_type = TYPE_NONE; break; } case XML_READER_TEXT: if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break; if ( data_pointer.e_type == TYPE_STRING ) *data_pointer.u_data.ppsz = strdup( p_node ); else if ( data_pointer.e_type == TYPE_LONG ) *data_pointer.u_data.pl = atol( p_node ); else if ( data_pointer.e_type == TYPE_INTEGER ) *data_pointer.u_data.pi = atoi( p_node ); break; case XML_READER_ENDELEM: if ( !p_entry ) break; if ( ! strcmp( p_node, "addon" ) ) { /* then append entry */ ARRAY_APPEND( p_finder->entries, p_entry ); p_entry = NULL; i_num_entries_created++; } data_pointer.e_type = TYPE_NONE; break; default: break; } } end: if ( p_entry ) /* Unclosed tag */ addon_entry_Release( p_entry ); xml_ReaderDelete( p_xml_reader ); return i_num_entries_created; }
static int LoadCatalog( addons_finder_t *p_finder ) { char *psz_path; char * psz_userdir = config_GetUserDir( VLC_DATA_DIR ); if ( !psz_userdir ) return VLC_ENOMEM; if ( asprintf( &psz_path, "%s%s", psz_userdir, ADDONS_CATALOG ) < 1 ) { free( psz_userdir ); return VLC_ENOMEM; } free( psz_userdir ); addon_entry_t *p_entry = NULL; const char *p_node; int i_current_node_type; int i_ret = VLC_SUCCESS; /* attr */ const char *attr, *value; /* temp reading */ char *psz_filename = NULL; int i_filetype = -1; struct stat stat_; if ( vlc_stat( psz_path, &stat_ ) ) { free( psz_path ); return VLC_EGENERIC; } char *psz_catalog_uri = vlc_path2uri( psz_path, "file" ); free( psz_path ); if ( !psz_catalog_uri ) return VLC_EGENERIC; stream_t *p_stream = stream_UrlNew( p_finder, psz_catalog_uri ); free( psz_catalog_uri ); if (! p_stream ) return VLC_EGENERIC; xml_reader_t *p_xml_reader = xml_ReaderCreate( p_finder, p_stream ); if( !p_xml_reader ) { stream_Delete( p_stream ); return VLC_EGENERIC; } if( xml_ReaderNextNode( p_xml_reader, &p_node ) != XML_READER_STARTELEM ) { msg_Err( p_finder, "invalid catalog" ); i_ret = VLC_EGENERIC; goto end; } if ( strcmp( p_node, "videolan") ) { msg_Err( p_finder, "unsupported catalog data format" ); i_ret = VLC_EGENERIC; goto end; } while( (i_current_node_type = xml_ReaderNextNode( p_xml_reader, &p_node )) > 0 ) { switch( i_current_node_type ) { case XML_READER_STARTELEM: { if ( ! strcmp( p_node, "addon" ) ) { if ( p_entry ) /* ?!? Unclosed tag */ addon_entry_Release( p_entry ); p_entry = addon_entry_New(); //p_entry->psz_source_module = strdup( ADDONS_MODULE_SHORTCUT ); p_entry->e_flags = ADDON_MANAGEABLE; p_entry->e_state = ADDON_INSTALLED; while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if ( !strcmp( attr, "type" ) ) { p_entry->e_type = ReadType( value ); } else if ( !strcmp( attr, "id" ) ) { addons_uuid_read( value, & p_entry->uuid ); } else if ( !strcmp( attr, "downloads" ) ) { p_entry->i_downloads = atoi( value ); if ( p_entry->i_downloads < 0 ) p_entry->i_downloads = 0; } else if ( !strcmp( attr, "score" ) ) { p_entry->i_score = atoi( value ); if ( p_entry->i_score < 0 ) p_entry->i_score = 0; else if ( p_entry->i_score > ADDON_MAX_SCORE ) p_entry->i_score = ADDON_MAX_SCORE; } else if ( !strcmp( attr, "source" ) ) { p_entry->psz_source_module = strdup( value ); } else if ( !strcmp( attr, "version" ) ) { p_entry->psz_version = strdup( value ); } } break; } if ( !p_entry ) break; BINDNODE("name", p_entry->psz_name, TYPE_STRING) BINDNODE("archive", p_entry->psz_archive_uri, TYPE_STRING) BINDNODE("summary", p_entry->psz_summary, TYPE_STRING) BINDNODE("description", p_entry->psz_description, TYPE_STRING) BINDNODE("image", p_entry->psz_image_data, TYPE_STRING) BINDNODE("resource", psz_filename, TYPE_STRING) BINDNODE("creator", p_entry->psz_author, TYPE_STRING) BINDNODE("sourceurl", p_entry->psz_source_uri, TYPE_STRING) data_pointer.e_type = TYPE_NONE; if ( ! strcmp( p_node, "resource" ) ) { while( (attr = xml_ReaderNextAttr( p_xml_reader, &value )) ) { if ( !strcmp( attr, "type" ) ) { i_filetype = ReadType( value ); } } } break; } case XML_READER_TEXT: if ( data_pointer.e_type == TYPE_NONE || !p_entry ) break; if ( data_pointer.e_type == TYPE_STRING ) *data_pointer.u_data.ppsz = strdup( p_node ); else if ( data_pointer.e_type == TYPE_LONG ) *data_pointer.u_data.pl = atol( p_node ); else if ( data_pointer.e_type == TYPE_INTEGER ) *data_pointer.u_data.pi = atoi( p_node ); break; case XML_READER_ENDELEM: if ( !p_entry ) break; if ( ! strcmp( p_node, "addon" ) ) { /* then append entry */ ARRAY_APPEND( p_finder->entries, p_entry ); p_entry = NULL; } if ( ! strcmp( p_node, "resource" ) ) { if ( p_entry && psz_filename && i_filetype >= 0 ) { addon_file_t *p_file = malloc( sizeof(addon_file_t) ); p_file->e_filetype = i_filetype; p_file->psz_filename = psz_filename; p_file->psz_download_uri = NULL; ARRAY_APPEND( p_entry->files, p_file ); } /* reset temp */ psz_filename = NULL; i_filetype = -1; } data_pointer.e_type = TYPE_NONE; break; default: break; } } end: if ( p_entry ) /* ?!? Unclosed tag */ addon_entry_Release( p_entry ); xml_ReaderDelete( p_xml_reader ); stream_Delete( p_stream ); return i_ret; }
static void grab_by_option (FILE * out, const database_t * db, cvs_connection_t * s, const char * r_arg, const char * D_arg, version_t ** fetch, version_t ** fetch_end) { // Build an array of the paths that we're getting. FIXME - if changeset // versions were sorted we wouldn't need this. const char ** paths = NULL; const char ** paths_end = NULL; for (version_t ** i = fetch; i != fetch_end; ++i) { version_t * v = version_live (*i); assert (v && v->used && v->mark == SIZE_MAX); ARRAY_APPEND (paths, v->file->path); } assert (paths != paths_end); ARRAY_SORT (paths, (int(*)(const void *, const void *)) strcmp); const char * d = NULL; ssize_t d_len = SSIZE_MAX; for (const char ** i = paths; i != paths_end; ++i) { const char * slash = strrchr (*i, '/'); if (slash == NULL) continue; if (slash - *i == d_len && memcmp (*i, d, d_len) == 0) continue; // Tell the server about this directory. d = *i; d_len = slash - d; cvs_printf (s, "Directory %s/%.*s\n" "%s%.*s\n", s->module, (int) d_len, d, s->prefix, (int) d_len, d); } // Go to the main directory. cvs_printf (s, "Directory %s\n%.*s\n", s->module, (int) (strlen (s->prefix) - 1), s->prefix); // Update args: if (r_arg) cvs_printf (s, "Argument -r%s\n", r_arg); if (D_arg) cvs_printf (s, "Argument -D%s\n", D_arg); cvs_printf (s, "Argument -kk\n" "Argument --\n"); for (const char ** i = paths; i != paths_end; ++i) cvs_printf (s, "Argument %s\n", *i); xfree (paths); cvs_printff (s, "update\n"); read_versions (out, db, s); }
static int Open( vlc_object_t *p_this ) { stream_t *s = (stream_t*)p_this; stream_sys_t *p_sys; if( !isSmoothStreaming( s ) || s->psz_url == NULL ) return VLC_EGENERIC; msg_Info( p_this, "Smooth Streaming (%s)", s->psz_url ); s->p_sys = p_sys = calloc( 1, sizeof(*p_sys ) ); if( unlikely( p_sys == NULL ) ) return VLC_ENOMEM; char *uri = strdup( s->psz_url ); if( unlikely( uri == NULL ) ) { free( p_sys ); return VLC_ENOMEM; } /* remove the last part of the url */ char *pos = strrchr( uri, '/'); *pos = '\0'; p_sys->download.base_url = uri; ARRAY_INIT( p_sys->sms ); ARRAY_INIT( p_sys->sms_selected ); /* Parse SMS ismc content. */ if( parse_Manifest( s ) != VLC_SUCCESS ) { SysCleanup( p_sys ); free( p_sys ); return VLC_EGENERIC; } if( !p_sys->vod_duration ) p_sys->b_live = true; /* Choose first video / audio / subtitle stream available */ sms_stream_t *selected = NULL; FOREACH_ARRAY( sms_stream_t *sms, p_sys->sms ); selected = SMS_GET_SELECTED_ST( sms->type ); if( !selected ) ARRAY_APPEND( p_sys->sms_selected, sms ); FOREACH_END(); /* Choose lowest quality for the first chunks */ FOREACH_ARRAY( sms_stream_t *sms, p_sys->sms ); quality_level_t *wanted = NULL; if ( sms->qlevels.i_size ) { wanted = sms->qlevels.p_elems[0]; for( int i=1; i < sms->qlevels.i_size; i++ ) { if( sms->qlevels.p_elems[i]->Bitrate < wanted->Bitrate ) wanted = sms->qlevels.p_elems[i]; } sms->current_qlvl = wanted; } FOREACH_END(); /* Init our playback queue */ p_sys->p_current_stream = next_playback_stream( p_sys ); if ( !p_sys->p_current_stream ) { SysCleanup( p_sys ); free( p_sys ); return VLC_EGENERIC; } p_sys->playback.next_chunk_offset = CHUNK_OFFSET_UNSET; p_sys->i_probe_length = SMS_PROBE_LENGTH; vlc_mutex_init( &p_sys->lock ); vlc_cond_init( &p_sys->download.wait ); vlc_cond_init( &p_sys->playback.wait ); vlc_mutex_init( &p_sys->playback.lock ); /* */ s->pf_read = Read; s->pf_control = Control; if( vlc_clone( &p_sys->download.thread, sms_Thread, s, VLC_THREAD_PRIORITY_INPUT ) ) { SysCleanup( p_sys ); vlc_mutex_destroy( &p_sys->lock ); vlc_cond_destroy( &p_sys->download.wait ); vlc_mutex_destroy( &p_sys->playback.lock ); vlc_cond_destroy( &p_sys->playback.wait ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
static int parse_Manifest( stream_t *s ) { stream_sys_t *p_sys = s->p_sys; xml_reader_t *vlc_reader = NULL; int type = UNKNOWN_ES; const char *name, *value; stream_t *st = s->p_source; msg_Dbg( s, "Manifest parsing\n" ); vlc_reader = xml_ReaderCreate( st, st ); if( !vlc_reader ) { msg_Err( s, "Failed to open source for parsing" ); return VLC_EGENERIC; } const char *node; uint8_t *WaveFormatEx; sms_stream_t *sms = NULL; quality_level_t *ql = NULL; custom_attrs_t *cp = NULL; int64_t start_time = 0, duration = 0; int64_t computed_start_time = 0, computed_duration = 0; unsigned next_track_id = 1; int loop_count = 0; bool b_weird = false; int ret = VLC_SUCCESS; #define TIMESCALE 10000000 while( (type = xml_ReaderNextNode( vlc_reader, &node )) > 0 ) { switch( type ) { case XML_READER_STARTELEM: if( !strcmp( node, "SmoothStreamingMedia" ) ) { while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Duration" ) ) p_sys->vod_duration = strtoull( value, NULL, 10 ); else if( !strcmp( name, "TimeScale" ) ) p_sys->timescale = strtoul( value, NULL, 10 ); else if ( !strcmp( name, "LookAheadFragmentCount" ) ) p_sys->download.lookahead_count = strtoul( value, NULL, 10 ); } if( !p_sys->timescale ) p_sys->timescale = TIMESCALE; } else if( !strcmp( node, "StreamIndex" ) ) { sms_Free( sms ); sms = sms_New(); if( unlikely( !sms ) ) { ret = VLC_ENOMEM; goto cleanup; } sms->id = next_track_id; next_track_id++; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Type" ) ) { if( !strcmp( value, "video" ) ) sms->type = VIDEO_ES; else if( !strcmp( value, "audio" ) ) sms->type = AUDIO_ES; else if( !strcmp( value, "text" ) ) sms->type = SPU_ES; } else if( !strcmp( name, "Name" ) ) sms->name = strdup( value ); else if( !strcmp( name, "TimeScale" ) ) sms->timescale = strtoull( value, NULL, 10 ); else if( !strcmp( name, "FourCC" ) ) sms->default_FourCC = VLC_FOURCC( value[0], value[1], value[2], value[3] ); else if( !strcmp( name, "Chunks" ) ) { sms->vod_chunks_nb = strtoul( value, NULL, 10 ); if( sms->vod_chunks_nb == 0 ) /* live */ sms->vod_chunks_nb = UINT32_MAX; } else if( !strcmp( name, "QualityLevels" ) ) sms->qlevel_nb = strtoul( value, NULL, 10 ); else if( !strcmp( name, "Url" ) ) sms->url_template = strdup(value); } if( !sms->timescale ) sms->timescale = TIMESCALE; if( !sms->name ) { if( sms->type == VIDEO_ES ) sms->name = strdup( "video" ); else if( sms->type == AUDIO_ES ) sms->name = strdup( "audio" ); else if( sms->type == SPU_ES ) sms->name = strdup( "text" ); } } else if ( !strcmp( node, "CustomAttributes" ) ) { if (!sms || !ql || cp) break; cp = (custom_attrs_t *) calloc( 1, sizeof(*cp) ); if( unlikely( !cp ) ) { ret = VLC_ENOMEM; goto cleanup; } } else if ( !strcmp( node, "Attribute" ) ) { if (!sms || !ql || !cp) break; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Name" ) && !cp->psz_key ) cp->psz_key = strdup( value ); else if( !strcmp( name, "Value" ) && !cp->psz_value ) cp->psz_value = strdup( value ); } } else if( !strcmp( node, "QualityLevel" ) ) { if ( !sms ) break; ql = ql_New(); if( !ql ) { ret = VLC_ENOMEM; goto cleanup; } while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "Index" ) ) ql->Index = strtol( value, NULL, 10 ); else if( !strcmp( name, "Bitrate" ) ) ql->Bitrate = strtoul( value, NULL, 10 ); else if( !strcmp( name, "PacketSize" ) ) ql->nBlockAlign = strtoul( value, NULL, 10 ); else if( !strcmp( name, "FourCC" ) ) ql->FourCC = VLC_FOURCC( value[0], value[1], value[2], value[3] ); else if( !strcmp( name, "CodecPrivateData" ) ) ql->CodecPrivateData = strdup( value ); else if( !strcmp( name, "WaveFormatEx" ) ) { WaveFormatEx = decode_string_hex_to_binary( value ); uint16_t data_len = ((uint16_t *)WaveFormatEx)[8]; ql->CodecPrivateData = strndup( value + 36, data_len * 2 ); uint16_t wf_tag = ((uint16_t *)WaveFormatEx)[0]; wf_tag_to_fourcc( wf_tag, &ql->FourCC, NULL ); ql->Channels = ((uint16_t *)WaveFormatEx)[1]; ql->SamplingRate = ((uint32_t *)WaveFormatEx)[1]; ql->nBlockAlign = ((uint16_t *)WaveFormatEx)[6]; ql->BitsPerSample = ((uint16_t *)WaveFormatEx)[7]; free( WaveFormatEx ); } else if( !strcmp( name, "MaxWidth" ) || !strcmp( name, "Width" ) ) ql->MaxWidth = strtoul( value, NULL, 10 ); else if( !strcmp( name, "MaxHeight" ) || !strcmp( name, "Height" ) ) ql->MaxHeight = strtoul( value, NULL, 10 ); else if( !strcmp( name, "Channels" ) ) ql->Channels = strtoul( value, NULL, 10 ); else if( !strcmp( name, "SamplingRate" ) ) ql->SamplingRate = strtoul( value, NULL, 10 ); else if( !strcmp( name, "BitsPerSample" ) ) ql->BitsPerSample = strtoul( value, NULL, 10 ); } ARRAY_APPEND( sms->qlevels, ql ); } else if ( !strcmp( node, "Content" ) && sms && !sms->url_template ) { /* empty(@Url) && ./Content == manifest embedded content */ sms_Free( sms ); sms = NULL; } else if( !strcmp( node, "c" ) ) { if ( !sms ) break; loop_count++; start_time = duration = -1; while( (name = xml_ReaderNextAttr( vlc_reader, &value )) ) { if( !strcmp( name, "t" ) ) start_time = strtoll( value, NULL, 10 ); if( !strcmp( name, "d" ) ) duration = strtoll( value, NULL, 10 ); } if( start_time == -1 ) { assert( duration != -1 ); computed_start_time += computed_duration; computed_duration = duration; } else if( duration == -1 ) { assert( start_time != -1 ); /* Handle weird Manifests which give only the start time * of the first segment. In those cases, we have to look * at the start time of the second segment to compute * the duration of the first one. */ if( loop_count == 1 ) { b_weird = true; computed_start_time = start_time; continue; } computed_duration = start_time - computed_start_time; if( !b_weird ) computed_start_time = start_time; } else { if( b_weird ) computed_duration = start_time - computed_start_time; else { computed_start_time = start_time; computed_duration = duration; } } if( unlikely( chunk_AppendNew( sms, computed_duration, computed_start_time ) == NULL ) ) { ret = VLC_ENOMEM; goto cleanup; } if( b_weird && start_time != -1 ) computed_start_time = start_time; } break; case XML_READER_ENDELEM: if ( !strcmp( node, "CustomAttributes" ) ) { if ( cp ) { ARRAY_APPEND(ql->custom_attrs, cp); cp = NULL; } } else if ( !strcmp( node, "Attribute" ) ) { if( !cp->psz_key || !cp->psz_value ) { cleanup_attributes( &cp ); } } else if( strcmp( node, "StreamIndex" ) ) break; else if ( sms ) { ARRAY_APPEND( p_sys->sms, sms ); computed_start_time = 0; computed_duration = 0; loop_count = 0; if( b_weird && !chunk_AppendNew( sms, computed_duration, computed_start_time ) ) { ret = VLC_ENOMEM; goto cleanup; } b_weird = false; if( sms->qlevel_nb == 0 ) sms->qlevel_nb = sms->qlevels.i_size; sms = NULL; } break; case XML_READER_TEXT: break; default: ret = VLC_EGENERIC; goto cleanup; } } #undef TIMESCALE cleanup: cleanup_attributes( &cp ); sms_Free( sms ); xml_ReaderDelete( vlc_reader ); return ret; }
void str_tokenize(char *string, char ***tokens, int *token_count) { /* 1. Initialize the result object. */ struct { char **data; int size, cap; } result = { NULL, 0, 0 }; /* 2. Iterate over the tokens in the string. */ while (*string) { /* 2.1. Find non-space character or end of string. */ while (*string && isspace(*string)) { ++string; } /* 2.2. All spaces until the end of string - no more tokens. */ if (*string == '\0') { goto end; } /* 2.3. Check if quoted token or a regular one. */ if (*string == '"') { /* 2.3.b.1. Store token beginning address. */ ARRAY_APPEND(result, ++string); /* 2.3.b.2. Find terminating quote or end of string. */ while (*string && *string != '"') { ++string; } /* 2.3.b.3 End of string reached? No more tokens. */ if (*string == '\0') { fprintf(stderr, "End of string while looking for terminating quote\n"); exit(1); } /* 2.3.b.4. If not at the end of string, end token with synthethic NUL. */ *string = '\0'; } else { /* 2.3.b.1. Store token beginning address. */ ARRAY_APPEND(result, string); /* 2.3.b.2. Find space character or end of string. */ while (*string && !isspace(*string)) { ++string; } /* 2.3.b.3 End of string reached? No more tokens. */ if (*string == '\0') { goto end; } /* 2.3.b.4. If not at the end of string, end token with synthethic NUL. */ *string = '\0'; } /* 2.4. Next char. */ ++string; } end: *tokens = result.data; *token_count = result.size; }
void create_changesets (database_t * db) { size_t total_versions = 0; for (file_t * i = db->files; i != db->files_end; ++i) total_versions += i->versions_end - i->versions; if (total_versions == 0) return; version_t ** version_list = ARRAY_ALLOC (version_t *, total_versions); version_t ** vp = version_list; for (file_t * i = db->files; i != db->files_end; ++i) for (version_t * j = i->versions; j != i->versions_end; ++j) *vp++ = j; assert (vp == version_list + total_versions); qsort (version_list, total_versions, sizeof (version_t *), version_compare_qsort); changeset_t * current = database_new_changeset (db); ARRAY_APPEND (current->versions, version_list[0]); version_list[0]->commit = current; current->time = version_list[0]->time; current->type = ct_commit; for (size_t i = 1; i < total_versions; ++i) { version_t * next = version_list[i]; if (!strings_match (*current->versions, next) || next->time - current->time > fuzz_span || next->time - current->versions_end[-1]->time > fuzz_gap) { ARRAY_TRIM (current->versions); current = database_new_changeset (db); current->time = next->time; current->type = ct_commit; } ARRAY_APPEND (current->versions, version_list[i]); version_list[i]->commit = current; } ARRAY_TRIM (current->versions); free (version_list); // Do a pass through the changesets; this breaks any cycles. heap_t ready_versions; heap_init (&ready_versions, offsetof (version_t, ready_index), version_compare_heap); prepare_for_emission (db, &ready_versions); ssize_t emitted_changesets = 0; changeset_t * changeset; while ((changeset = next_changeset_split (db, &ready_versions))) { changeset_emitted (db, &ready_versions, changeset); ++emitted_changesets; } // Sort the changeset version lists by file. for (changeset_t ** i = db->changesets; i != db->changesets_end; ++i) ARRAY_SORT ((*i)->versions, compare_version_by_file); assert (heap_empty (&ready_versions)); assert (heap_empty (&db->ready_changesets)); assert (emitted_changesets == db->changesets_end - db->changesets); heap_destroy (&ready_versions); }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "dump-vcode", optional_argument, 0, 'v' }, { "prefer-explicit", no_argument, 0, 'p' }, // DEPRECATED { "relax", required_argument, 0, 'r' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': fatal("unrecognised analyse option %s", argv[optind - 1]); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'v': opt_set_str("dump-vcode", optarg ?: ""); break; case 'p': warnf("the --prefer-explict option is deprecated: use " "--relax=prefer-explict instead"); opt_set_int("relax", RELAX_PREFER_EXPLICT); break; case 'r': opt_set_int("relax", parse_relax(optarg)); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) { lower_unit(units[i]); cgen(units[i]); } } return EXIT_SUCCESS; }
static int ListSkins( addons_finder_t *p_finder ) { char *psz_dir = getAddonInstallDir( ADDON_SKIN2 ); if ( !psz_dir ) return VLC_EGENERIC; char **ppsz_list = NULL; int i_count = vlc_scandir( psz_dir, &ppsz_list, ListSkin_filter, NULL ); for ( int i=0; i< i_count; i++ ) { char *psz_file = ppsz_list[i]; if( !psz_file ) break; if ( FileBelongsToManagedAddon( p_finder, ADDON_SKIN2, psz_file ) ) continue; char *psz_uri; if( asprintf( &psz_uri, "unzip://%s/%s!/theme.xml", psz_dir, psz_file ) >= 0) { int i_ret; char *psz_name = NULL; char *psz_source = NULL; stream_t *p_stream = stream_UrlNew( p_finder, psz_uri ); free( psz_uri ); if ( !p_stream ) { i_ret = VLC_EGENERIC; } else { i_ret = ParseSkins2Info( p_finder, p_stream, &psz_name, &psz_source ); if ( i_ret != VLC_SUCCESS ) { free( psz_name ); free( psz_source ); } stream_Delete( p_stream ); } addon_entry_t *p_entry = addon_entry_New(); p_entry->e_type = ADDON_SKIN2; p_entry->e_state = ADDON_INSTALLED; if ( i_ret == VLC_SUCCESS ) { p_entry->psz_name = psz_name; p_entry->psz_description = strdup("Skins2 theme"); p_entry->psz_source_uri = psz_source; } else { p_entry->e_flags |= ADDON_BROKEN; p_entry->psz_name = strdup(psz_file); p_entry->psz_description = strdup("Skins2 theme"); } ARRAY_APPEND( p_finder->entries, p_entry ); } free( psz_file ); } free( ppsz_list ); free( psz_dir ); return VLC_SUCCESS; }
/// Output the fixups that must be done before the given time. If none, then no /// commit is created. void print_fixups (FILE * out, const database_t * db, version_t ** base_versions, tag_t * tag, const changeset_t * cs, cvs_connection_t * s) { fixup_ver_t * fixups; fixup_ver_t * fixups_end; fixup_list (&fixups, &fixups_end, tag, cs); if (fixups == fixups_end) return; // base_versions should only be NULL for starting the trunk. But that // should never need fixups. assert (base_versions != NULL); // If we're doing fixups for a branch, then the base_versions should be the // branch version. assert (tag->branch_versions == NULL || base_versions == tag->branch_versions); version_t ** fetch = NULL; version_t ** fetch_end = NULL; for (fixup_ver_t * ffv = fixups; ffv != fixups_end; ++ffv) if (ffv->version != NULL && !ffv->version->dead && ffv->version->mark == SIZE_MAX) ARRAY_APPEND (fetch, ffv->version); // FIXME - grab_versions assumes that all versions are on the same branch! // We should pass in the tag rather than guessing it! grab_versions (out, db, s, fetch, fetch_end); xfree (fetch); tag->fixup = true; size_t from = tag->changeset.mark; tag->changeset.mark = ++mark_counter; if (tag->deleted) fprintf (out, "commit _crap_zombie\n"); else fprintf (out, "commit %s/%s\n", tag->branch_versions ? branch_prefix : tag_prefix, *tag->tag ? tag->tag : master); fprintf (out, "mark :%zu\n", tag->changeset.mark); fprintf (out, "committer crap <crap> %ld +0000\n", tag->branch_versions && tag->last ? tag->last->time : tag->changeset.time); const char * comment = fixup_commit_comment ( db, base_versions, fixups, fixups_end); fprintf (out, "data %zu\n%s", strlen (comment), comment); xfree (comment); if (tag->deleted) fprintf (out, "from :%zu\n", from); // We need a list of versions for updating the entries files. If we are // working on a branch, then we need to update that anyway. Else take a // temporary list. version_t ** updated_versions = tag->branch_versions; if (updated_versions == NULL) { size_t bytes = (db->files_end - db->files) * sizeof (version_t *); updated_versions = xmalloc (bytes); memcpy (updated_versions, base_versions, bytes); } for (fixup_ver_t * ffv = fixups; ffv != fixups_end; ++ffv) { int i = ffv->file - db->files; version_t * tv = ffv->version; assert (tv != version_live (updated_versions[i])); updated_versions[i] = tv; } const char * last_path = NULL; for (fixup_ver_t * ffv = fixups; ffv != fixups_end; ++ffv) { version_t * tv = ffv->version; if (tv == NULL) fprintf (out, "D %s\n", ffv->file->path); else fprintf (out, "M %s :%zu %s\n", tv->exec ? "755" : "644", tv->mark, tv->file->path); last_path = output_entries_list ( out, db, updated_versions, ffv->file, last_path); } if (tag->branch_versions == NULL) xfree (updated_versions); xfree (fixups); }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "prefer-explicit", no_argument, 0, 'p' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'p': opt_set_int("prefer-explicit", 1); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) cgen(units[i]); } return EXIT_SUCCESS; }