/* * Copyright (C) 2007, 2008 OpenedHand Ltd. * Authored by: Rob Bradford * * This is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, version 2 of the License. * * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "beaver-util.h" /* * Callback that gets fired when data gets flushed in the view because it's * the end of line */ void beaver_util_message_view_buffer_flushed_cb (IAnjutaMessageView *view, gchar *data, gpointer userdata) { /* Append to the message view */ ianjuta_message_view_append (view, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, data, "", NULL); } /* do not free the strings in the returned vector but do free the vector */ gchar ** beaver_util_strv_concat (gchar **strv_1, gchar **strv_2) { gchar **res = NULL; gchar **p = NULL; res = g_new0 (gchar *, g_strv_length (strv_1) + g_strv_length (strv_2) + 1); p = res; while (*strv_1 != NULL) { *p = *strv_1; p++; strv_1++; } while (*strv_2 != NULL) { *p = *strv_2; p++; strv_2++; } *p = NULL; return res; } gchar ** beaver_util_strv_joinv (gchar **strv_1, ...) { gchar **res; gchar **strv_j; gint i; gint items; va_list args; va_start (args, strv_1); items = g_strv_length (strv_1); res = g_malloc0 ((items + 1) * sizeof (gchar *)); i = 0; while (*strv_1 != NULL) { res[i] = *strv_1; i++; strv_1++; } while ((strv_j = va_arg (args, gchar **)) != NULL) { items += g_strv_length (strv_j); res = g_realloc (res, (items + 1) * sizeof (gchar *)); while (*strv_j != NULL) { res[i] = *strv_j; i++; strv_j++; } } va_end (args); res[i] = NULL; return res; } /* Fetch supported target platforms by searching the environment-setup-XXX * files under poky_sdk_root or poky_tree tmpdir directories. it returns * a newly allocated char array which is needed to be freed if caller does * not use it anymore */ gchar * beaver_util_get_archs(gchar *directory) { DIR *dirp; struct dirent *entry; gchar *temp = NULL; gchar *support_arch_string = NULL; gchar *archname = NULL; errno = 0;//clear errno for catching errors dirp = opendir(directory); if (errno || !dirp) { g_warning("Error while trying to open directory %s: %s!", directory, g_strerror(errno)); return NULL; } //reset for logging errors errno = 0; while(entry = readdir(dirp)) { if (errno) { g_warning("Error while trying to read directory: %s!", g_strerror(errno)); goto end; } if (entry->d_type != DT_REG) continue; archname = entry->d_name; /* parse the valid environment script files, all valid platform names * will be connected together with , */ if (g_str_has_prefix(archname, ENV_SCRIPT_FILE_PREFIX)) { temp = support_arch_string; if (temp) support_arch_string = g_strconcat(temp, "," , archname + strlen(ENV_SCRIPT_FILE_PREFIX), NULL); else support_arch_string = g_strdup(archname + strlen(ENV_SCRIPT_FILE_PREFIX)); g_free(temp); } } g_debug("Get supported arch strings %s", support_arch_string); end: closedir(dirp); return support_arch_string; } /* when target platform selection changes and if we get valid * corresponding environment script file, we need to update the * ENV storage hash table. Remember, before the first time * updating the environment settings, we need to keep the old * original settings for the conveniences of switching back * the old environment settings before activating this anjuta poky * SDK plugin * Plese Note: This is only a limited parser, if newer script * shell grammar is used, we should be very careful! */ void update_env_hash(gchar *filename, GHashTable *hash_configs, GHashTable **old_hash_configs) { FILE *fp; gchar buf[MAX_CONFIG_LENGTH], temp[MAX_CONFIG_LENGTH], value[MAX_CONFIG_LENGTH]; gchar *ret_buf, *key; gint i = 0; gboolean save = FALSE; const gchar *env_value; fp = fopen(filename, "r"); if (!fp) { g_warning("Error while opening config file %s!", filename); return; } /* the old environment settings are saved into one hash table. * It only needs save once after the poky SDK is activated */ if (*old_hash_configs) save = FALSE; else { *old_hash_configs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); save = TRUE; } while (!feof(fp)) { memset(value, 0, MAX_CONFIG_LENGTH); ret_buf = fgets(buf, MAX_CONFIG_LENGTH, fp); if (ret_buf) { //This is the mark of shell script, skip it for convenience! //Otherwise, if user modify scripts, it will be wrong ret_buf = g_strstrip(ret_buf); if (g_str_has_prefix(ret_buf, "#")) continue; if (g_str_has_prefix(ret_buf, "export")) { ret_buf += strlen("export"); ret_buf = g_strstrip(ret_buf); i = 0; while(ret_buf && (*ret_buf != '=')) temp[i++] = *(ret_buf++); temp[i] = '\0'; key = g_strdup(temp); key = g_strstrip(key); ret_buf = g_strstrip(ret_buf); while(ret_buf && (*ret_buf == '=' || *ret_buf == '"' || *ret_buf == '\'')) ret_buf++; //we need very carefully deal with special chars... //currently we did it manually. Maybe those special //keys need more processing i = 0; while(ret_buf && (*ret_buf != '"') && (*ret_buf != '\n') && (*ret_buf != '\r') && (*ret_buf != '\'')) value[i++] = *(ret_buf++); value[i] = '\0'; g_debug("NEW ENV key %s, val %s, len %d", key, value, strlen(value)); /* Please note that hash table key and value must use g_free * destroyer since it used dynamic allocation mechanism, so * that we defined g_free in the g_new_hash_table_full create function */ g_hash_table_insert(hash_configs, key, g_strstrip(g_strdup(value))); /* Note: if the old environment variables have never been saved before, * we will save the old env vars to the hash table for later * environment variables restore usage */ if (save) { env_value = g_getenv (key); g_debug("Save old ENV: key %s value %s", key, env_value); if (env_value) g_hash_table_insert(*old_hash_configs, g_strdup(key), g_strdup(env_value)); } } } } fclose(fp); } /* update_combo_box need to be called when poky mode * selection radio changes, sdk_root directory changes * and poky_root directory changes. It updates the combo * box text items according to the changed directory * environment-setupXXX files.*/ void update_combo_box(GtkWidget *p_combo_box, gchar *target_archs) { GtkTreeModel *model; gint count, i; gchar **vstr, *active_text; if (!p_combo_box) { g_warning("Error while fetching combo_box widget!"); return; } model = gtk_combo_box_get_model(GTK_COMBO_BOX(p_combo_box)); count = gtk_tree_model_iter_n_children(model, NULL); //Firstly remove all old text items in the combo_box for(i = count - 1; i >= 0; i--) gtk_combo_box_remove_text(GTK_COMBO_BOX(p_combo_box), i); if (!target_archs || strlen(target_archs) <= 0) { gtk_widget_set_sensitive(p_combo_box, FALSE); return; } else { vstr = g_strsplit (target_archs, ",", 0); if (vstr) { active_text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(p_combo_box)); for (i = 0; vstr[i]; i++) { gtk_combo_box_append_text (GTK_COMBO_BOX(p_combo_box), vstr[i]); //set back old valid selected text for better user experiences if (strcmp(vstr[i], active_text) == 0) gtk_combo_box_set_active(GTK_COMBO_BOX(p_combo_box), i); } gtk_widget_set_sensitive(p_combo_box, TRUE); g_free(active_text); } g_strfreev (vstr); } }