2008-02-11 Johannes Schmid <jhs@gnome.org>
[anjuta-git-plugin.git] / src / utilities.c
blob03356551ca5e9844529a68989cb85af6778bb48e
1 /*
2 utilities.c
3 Copyright (C) 2000 Kh. Naba Kumar Singh
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #include <errno.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/wait.h>
27 #include <sys/stat.h>
28 #include <limits.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <glib.h>
33 #include <gtk/gtk.h>
35 #include <libanjuta/resources.h>
37 #include "anjuta.h"
38 #include "utilities.h"
39 #include "launcher.h"
40 #include "properties.h"
42 const gchar *
43 extract_filename (const gchar * full_filename)
46 gint i;
47 gint length;
49 if (!full_filename)
50 return NULL;
51 length = strlen (full_filename);
52 if (length == 0)
53 return full_filename;
54 if (full_filename[length - 1] == '/')
55 return &full_filename[length];
56 for (i = length - 1; i >= 0; i--)
57 if (full_filename[i] == '/')
58 break;
59 if (i == 0 && full_filename[0] != '/')
60 return full_filename;
61 return &full_filename[++i];
64 gchar*
65 extract_directory(const gchar* full_filename)
67 gint i;
68 gint length;
69 gchar* dir;
71 if (!full_filename)
72 return NULL;
73 length = strlen (full_filename);
74 if (length == 0)
75 return g_strdup(full_filename);
76 if (full_filename[length - 1] == '/')
78 dir = g_new0(char, length - 1);
79 strncpy(dir, full_filename, length - 2);
80 return dir;
82 for (i = length - 1; i >= 0; i--)
83 if (full_filename[i] == '/')
84 break;
85 if (i == 0)
86 return g_strdup("");
87 dir = g_new0(char, i + 1);
88 strncpy(dir, full_filename, i);
89 dir[i] = '\0';
90 return dir;
93 void
94 free_string_list ( GList * pList )
96 int i ;
98 if( pList )
100 for (i = 0; i < g_list_length (pList); i++)
101 g_free (g_list_nth (pList, i)->data);
103 g_list_free (pList);
109 gboolean
110 parse_error_line (const gchar * line, gchar ** filename, int *lineno)
112 gint i = 0;
113 gint j = 0;
114 gint k = 0;
115 gchar *dummy;
117 while (line[i++] != ':')
119 if (i >= strlen (line) || i >= 512 || line[i - 1] == ' ')
121 goto down;
124 if (isdigit (line[i]))
126 j = i;
127 while (isdigit (line[i++])) ;
128 dummy = g_strndup (&line[j], i - j - 1);
129 *lineno = atoi (dummy);
130 if (dummy)
131 g_free (dummy);
132 dummy = g_strndup (line, j - 1);
133 *filename = g_strdup (g_strstrip (dummy));
134 if (dummy)
135 g_free (dummy);
136 return TRUE;
139 down:
140 i = strlen (line) - 1;
141 while (isspace (line[i]) == FALSE)
143 i--;
144 if (i < 0)
146 *filename = NULL;
147 *lineno = 0;
148 return FALSE;
151 k = i++;
152 while (line[i++] != ':')
154 if (i >= strlen (line) || i >= 512 || line[i - 1] == ' ')
156 *filename = NULL;
157 *lineno = 0;
158 return FALSE;
161 if (isdigit (line[i]))
163 j = i;
164 while (isdigit (line[i++])) ;
165 dummy = g_strndup (&line[j], i - j - 1);
166 *lineno = atoi (dummy);
167 if (dummy)
168 g_free (dummy);
169 dummy = g_strndup (&line[k], j - k - 1);
170 *filename = g_strdup (g_strstrip (dummy));
171 if (dummy)
172 g_free (dummy);
173 return TRUE;
175 *lineno = 0;
176 *filename = NULL;
177 return FALSE;
180 gchar *
181 get_file_extension (gchar * file)
183 gchar *pos;
184 if (!file)
185 return NULL;
186 pos = strrchr (file, '.');
187 if (pos)
188 return ++pos;
189 else
190 return NULL;
193 FileExtType get_file_ext_type (gchar * file)
195 gchar *pos, *filetype_str;
196 FileExtType filetype;
198 if (!file)
199 return FILE_TYPE_UNKNOWN;
200 pos = get_file_extension (file);
201 if (pos == NULL)
202 return FILE_TYPE_UNKNOWN;
204 filetype_str =
205 prop_get_new_expand (ANJUTA_PREFERENCES (app->preferences)->props,
206 "filetype.", file);
207 if (filetype_str == NULL)
208 return FILE_TYPE_UNKNOWN;
210 if (strcmp (filetype_str, "c") == 0)
212 filetype = FILE_TYPE_C;
214 else if (strcmp (filetype_str, "cpp") == 0)
216 filetype = FILE_TYPE_CPP;
218 else if (strcmp (filetype_str, "header") == 0)
220 filetype = FILE_TYPE_HEADER;
222 else if (strcmp (filetype_str, "pascal") == 0)
224 filetype = FILE_TYPE_PASCAL;
226 else if (strcmp (filetype_str, "rc") == 0)
228 filetype = FILE_TYPE_RC;
230 else if (strcmp (filetype_str, "idl") == 0)
232 filetype = FILE_TYPE_IDL;
234 else if (strcmp (filetype_str, "cs") == 0)
236 filetype = FILE_TYPE_CS;
238 else if (strcmp (filetype_str, "java") == 0)
240 filetype = FILE_TYPE_JAVA;
242 else if (strcmp (filetype_str, "js") == 0)
244 filetype = FILE_TYPE_JS;
246 else if (strcmp (filetype_str, "conf") == 0)
248 filetype = FILE_TYPE_CONF;
250 else if (strcmp (filetype_str, "hypertext") == 0)
252 filetype = FILE_TYPE_HTML;
254 else if (strcmp (filetype_str, "xml") == 0)
256 filetype = FILE_TYPE_XML;
258 else if (strcmp (filetype_str, "latex") == 0)
260 filetype = FILE_TYPE_LATEX;
262 else if (strcmp (filetype_str, "lua") == 0)
264 filetype = FILE_TYPE_LUA;
266 else if (strcmp (filetype_str, "perl") == 0)
268 filetype = FILE_TYPE_PERL;
270 else if (strcmp (filetype_str, "shellscript") == 0)
272 filetype = FILE_TYPE_SH;
274 else if (strcmp (filetype_str, "python") == 0)
276 filetype = FILE_TYPE_PYTHON;
278 else if (strcmp (filetype_str, "ruby") == 0)
280 filetype = FILE_TYPE_RUBY;
282 else if (strcmp (filetype_str, "props") == 0)
284 filetype = FILE_TYPE_PROPERTIES;
286 else if (strcmp (filetype_str, "project") == 0)
288 filetype = FILE_TYPE_PROJECT;
290 else if (strcmp (filetype_str, "batch") == 0)
292 filetype = FILE_TYPE_BATCH;
294 else if (strcmp (filetype_str, "errorlist") == 0)
296 filetype = FILE_TYPE_ERRORLIST;
298 else if (strcmp (filetype_str, "makefile") == 0)
300 filetype = FILE_TYPE_MAKEFILE;
302 else if (strcmp (filetype_str, "iface") == 0)
304 filetype = FILE_TYPE_IFACE;
306 else if (strcmp (filetype_str, "diff") == 0)
308 filetype = FILE_TYPE_DIFF;
310 else if (strcmp (filetype_str, "icon") == 0)
312 filetype = FILE_TYPE_ICON;
314 else if (strcmp (filetype_str, "image") == 0)
316 filetype = FILE_TYPE_IMAGE;
318 else if (strcmp (filetype_str, "asm") == 0)
320 filetype = FILE_TYPE_ASM;
322 else if (strcmp (filetype_str, "scm") == 0)
324 filetype = FILE_TYPE_SCM;
326 else if (strcmp (filetype_str, "po") == 0)
328 filetype = FILE_TYPE_PO;
330 else if (strcmp (filetype_str, "sql") == 0)
332 filetype = FILE_TYPE_SQL;
334 else if (strcmp (filetype_str, "plsql") == 0)
336 filetype = FILE_TYPE_PLSQL;
338 else if (strcmp (filetype_str, "vb") == 0)
340 filetype = FILE_TYPE_VB;
342 else if (strcmp (filetype_str, "baan") == 0)
344 filetype = FILE_TYPE_BAAN;
346 else if (strcmp (filetype_str, "ada") == 0)
348 filetype = FILE_TYPE_ADA;
350 else if (strcmp (filetype_str, "wscript") == 0)
352 filetype = FILE_TYPE_WSCRIPT;
354 else if (strcmp (filetype_str, "lisp") == 0)
356 filetype = FILE_TYPE_LISP;
358 else if (strcmp (filetype_str, "matlab") == 0)
360 filetype = FILE_TYPE_MATLAB;
362 else
364 filetype = FILE_TYPE_UNKNOWN;
366 g_free (filetype_str);
367 return filetype;
370 gboolean write_line (FILE * stream, gchar * str)
372 unsigned long len;
374 if (!str || !stream)
375 return FALSE;
376 len = strlen (str);
377 if (len != 0)
378 if (fwrite (str, len, sizeof (gchar), stream) < 0)
379 return FALSE;
380 if (fwrite ("\n", 1, sizeof (gchar), stream) < 1)
381 return FALSE;
382 return TRUE;
385 gboolean read_line (FILE * stream, gchar ** str)
387 unsigned long count;
388 gchar buffer[1024];
389 gint ch;
391 if (stream == NULL)
392 return FALSE;
394 count = 0;
395 while (1)
397 ch = fgetc (stream);
398 if (ch < 0)
399 break;
400 if (ch == '\n')
401 break;
402 buffer[count] = (char) ch;
403 count++;
404 if (count >= 1024 - 1)
405 break;
407 buffer[count] = '\0';
408 *str = g_strdup (buffer);
409 return TRUE;
412 gboolean write_string (FILE * stream, gchar * t, gchar * str)
414 unsigned long len;
415 if (!str || !stream)
416 return FALSE;
417 len = strlen (str);
418 if (fprintf (stream, "%s :%lu: ", t, len) < 2)
419 return FALSE;
420 if (len != 0)
421 if (fwrite (str, len, sizeof (gchar), stream) < 0)
422 return FALSE;
423 if (fwrite ("\n", 1, sizeof (gchar), stream) < 1)
424 return FALSE;
425 return TRUE;
428 gboolean read_string (FILE * stream, gchar * t, gchar ** str)
430 unsigned long tmp;
431 gchar *buff, bb[3], token[256];
433 tmp = 0;
434 strcpy (token, "");
435 if (stream == NULL)
436 return FALSE;
437 if (fscanf (stream, "%s :%lu: ", token, &tmp) < 2)
438 return FALSE;
439 if (strcmp (token, t) != 0)
440 return FALSE;
441 if (tmp == 0)
443 if (str)
444 (*str) = g_strdup ("");
445 return TRUE;
447 buff = g_malloc ((tmp + 1) * sizeof (char));
448 if (fread (buff, tmp, sizeof (gchar), stream) < 0)
450 g_free (buff);
451 return FALSE;
453 if (fread (bb, 1, sizeof (gchar), stream) < 1)
455 g_free (buff);
456 return FALSE;
458 buff[tmp] = '\0';
459 if (str)
460 (*str) = buff;
461 else
462 g_free (buff);
463 return TRUE;
466 gint compare_string_func (gconstpointer a, gconstpointer b)
468 if (!a && !b)
469 return 0;
470 if (!a || !b)
471 return -1;
472 return (strcmp ((char *) a, (char *) b));
475 gboolean
476 file_is_regular (const gchar * fn)
478 struct stat st;
479 int ret;
480 if (!fn)
481 return FALSE;
482 ret = stat (fn, &st);
483 if (ret)
484 return FALSE;
485 if (S_ISREG (st.st_mode))
486 return TRUE;
487 return FALSE;
490 gboolean
491 file_is_directory (const gchar * fn)
493 struct stat st;
494 int ret;
495 if (!fn)
496 return FALSE;
497 ret = stat (fn, &st);
498 if (ret)
499 return FALSE;
500 if (S_ISDIR (st.st_mode))
501 return TRUE;
502 return FALSE;
505 gboolean
506 file_is_link (const gchar * fn)
508 struct stat st;
509 int ret;
510 if (!fn)
511 return FALSE;
512 ret = lstat (fn, &st);
513 if (ret)
514 return FALSE;
515 if (S_ISLNK (st.st_mode))
516 return TRUE;
517 return FALSE;
520 gboolean
521 file_is_char_device (const gchar * fn)
523 struct stat st;
524 int ret;
525 if (!fn)
526 return FALSE;
527 ret = stat (fn, &st);
528 if (ret)
529 return FALSE;
530 if (S_ISCHR (st.st_mode))
531 return TRUE;
532 return FALSE;
535 gboolean
536 file_is_block_device (const gchar * fn)
538 struct stat st;
539 int ret;
540 if (!fn)
541 return FALSE;
542 ret = stat (fn, &st);
543 if (ret)
544 return FALSE;
545 if (S_ISBLK (st.st_mode))
546 return TRUE;
547 return FALSE;
550 gboolean
551 file_is_fifo (const gchar * fn)
553 struct stat st;
554 int ret;
555 if (!fn)
556 return FALSE;
557 ret = stat (fn, &st);
558 if (ret)
559 return FALSE;
560 if (S_ISFIFO (st.st_mode))
561 return TRUE;
562 return FALSE;
565 gboolean
566 file_is_socket (const gchar * fn)
568 struct stat st;
569 int ret;
570 if (!fn)
571 return FALSE;
572 ret = stat (fn, &st);
573 if (ret)
574 return FALSE;
575 if (S_ISSOCK (st.st_mode))
576 return TRUE;
577 return FALSE;
580 gboolean
581 file_is_readable (const gchar * fn)
583 struct stat st;
584 int ret;
585 if (!fn)
586 return FALSE;
587 ret = stat (fn, &st);
588 if (ret)
589 return FALSE;
590 if (S_IRUSR & st.st_mode)
591 return TRUE;
592 return FALSE;
595 gboolean
596 file_is_readonly (const gchar * fn)
598 return file_is_readable (fn) && !file_is_writable (fn);
601 gboolean
602 file_is_readwrite (const gchar * fn)
604 return file_is_readable (fn) && file_is_writable (fn);
608 gboolean
609 file_is_writable (const gchar * fn)
611 struct stat st;
612 int ret;
613 if (!fn)
614 return FALSE;
615 ret = stat (fn, &st);
616 if (ret)
617 return FALSE;
618 if (S_IWUSR & st.st_mode)
619 return TRUE;
620 return FALSE;
623 gboolean
624 file_is_executable (const gchar * fn)
626 struct stat st;
627 int ret;
628 if (!fn)
629 return FALSE;
630 ret = stat (fn, &st);
631 if (ret)
632 return FALSE;
633 if (S_IXUSR & st.st_mode)
634 return TRUE;
635 return FALSE;
638 gboolean
639 file_is_suid (const gchar * fn)
641 struct stat st;
642 int ret;
643 if (!fn)
644 return FALSE;
645 ret = stat (fn, &st);
646 if (ret)
647 return FALSE;
648 if (S_ISUID & st.st_mode)
649 return TRUE;
650 return FALSE;
653 gboolean
654 file_is_sgid (const gchar * fn)
656 struct stat st;
657 int ret;
658 if (!fn)
659 return FALSE;
660 ret = stat (fn, &st);
661 if (ret)
662 return FALSE;
663 if (S_ISGID & st.st_mode)
664 return TRUE;
665 return FALSE;
668 gboolean
669 file_is_sticky (const gchar * fn)
671 struct stat st;
672 int ret;
673 if (!fn)
674 return FALSE;
675 ret = stat (fn, &st);
676 if (ret)
677 return FALSE;
678 if (S_ISVTX & st.st_mode)
679 return TRUE;
680 return FALSE;
683 gboolean
684 copy_file (gchar * src, gchar * dest, gboolean show_error)
686 FILE *input_fp, *output_fp;
687 gchar buffer[FILE_BUFFER_SIZE];
688 gint bytes_read, bytes_written;
689 gboolean error;
691 error = TRUE;
693 input_fp = fopen (src, "rb");
694 if (input_fp == NULL)
696 if( show_error)
697 anjuta_system_error (errno, _("Unable to read file: %s."), src);
698 return FALSE;
701 output_fp = fopen (dest, "wb");
702 if (output_fp == NULL)
704 if( show_error)
705 anjuta_system_error (errno, _("Unable to create file: %s."), dest);
706 fclose (input_fp);
707 return TRUE;
710 for (;;)
712 bytes_read = fread (buffer, 1, FILE_BUFFER_SIZE, input_fp);
713 if (bytes_read != FILE_BUFFER_SIZE && ferror (input_fp))
715 error = FALSE;
716 break;
719 if (bytes_read)
721 bytes_written = fwrite (buffer, 1, bytes_read, output_fp);
722 if (bytes_read != bytes_written)
724 error = FALSE;
725 break;
729 if (bytes_read != FILE_BUFFER_SIZE && feof (input_fp))
731 break;
735 fclose (input_fp);
736 fclose (output_fp);
738 if( show_error && (error == FALSE))
739 anjuta_system_error (errno, _("Unable to complete file copy"));
740 return error;
743 void
744 update_gtk ()
746 /* Do not update gtk when launcher is busy */
747 /* This will freeze the application till the launcher is done */
748 if (anjuta_launcher_is_busy (app->launcher) == TRUE)
749 return;
750 if (app->auto_gtk_update == FALSE)
751 return;
752 while (gtk_events_pending ())
754 gtk_main_iteration ();
758 void
759 entry_set_text_n_select (GtkWidget * entry, gchar * text,
760 gboolean use_selection)
762 if (!entry)
763 return;
764 if (GTK_IS_ENTRY (entry) == FALSE)
765 return;
767 if (use_selection)
769 gchar *chars = anjuta_get_current_selection ();
770 if (chars)
772 gtk_entry_set_text (GTK_ENTRY (entry), chars);
773 gtk_editable_select_region (GTK_EDITABLE (entry), 0,
774 strlen (gtk_entry_get_text
775 (GTK_ENTRY
776 (entry))));
778 g_free (chars);
780 else
782 if (text)
783 gtk_entry_set_text (GTK_ENTRY (entry), text);
784 gtk_editable_select_region (GTK_EDITABLE (entry), 0,
785 strlen (gtk_entry_get_text
786 (GTK_ENTRY
787 (entry))));
790 else
792 if (text)
793 gtk_entry_set_text (GTK_ENTRY (entry), text);
794 gtk_editable_select_region (GTK_EDITABLE (entry), 0,
795 strlen (gtk_entry_get_text
796 (GTK_ENTRY (entry))));
800 gboolean
801 force_create_dir (gchar * d)
803 if (file_is_directory (d))
804 return TRUE;
805 if (mkdir (d, 0755))
806 return FALSE;
807 return TRUE;
810 PangoFontDescription *
811 get_fixed_font ()
813 static PangoFontDescription *font_desc;
814 static gint done;
816 if (done)
817 return font_desc;
818 font_desc = pango_font_description_from_string ("misc medium 12");
819 done = 1;
820 if (font_desc)
822 // pango_font_ref (font);
823 return font_desc;
825 g_warning ("Cannot load fixed(misc) font. Using default font.");
826 return NULL;
829 gchar *
830 remove_white_spaces (gchar * text)
832 guint src_count, dest_count, tab_count;
833 gchar buff[2048]; /* Let us hope that it does not overflow */
835 tab_count =
836 anjuta_preferences_get_int (ANJUTA_PREFERENCES (app->preferences),
837 TAB_SIZE);
838 dest_count = 0;
839 for (src_count = 0; src_count < strlen (text); src_count++)
841 if (text[src_count] == '\t')
843 gint j;
844 for (j = 0; j < tab_count; j++)
845 buff[dest_count++] = ' ';
847 else if (isspace (text[src_count]))
849 buff[dest_count++] = ' ';
851 else
853 buff[dest_count++] = text[src_count];
856 buff[dest_count] = '\0';
857 return g_strdup (buff);
860 GList *
861 remove_blank_lines (GList * lines)
863 GList *list, *node;
864 gchar *str;
866 if (lines)
867 list = g_list_copy (lines);
868 else
869 list = NULL;
871 node = list;
872 while (node)
874 str = node->data;
875 node = g_list_next (node);
876 if (!str)
878 list = g_list_remove (list, str);
879 continue;
881 if (strlen (g_strchomp (str)) < 1)
882 list = g_list_remove (list, str);
884 return list;
887 gboolean widget_is_child (GtkWidget * parent, GtkWidget * child)
889 if (GTK_IS_CONTAINER (parent))
891 GList *children;
892 GList *node;
893 children = gtk_container_get_children (GTK_CONTAINER (parent));
894 node = children;
895 while (node)
897 if (widget_is_child (node->data, child))
898 return TRUE;
901 else
903 if (parent == child)
904 return TRUE;
906 return FALSE;
909 /* Assign a value to a string */
910 void
911 string_assign (gchar ** string, const gchar *value)
913 if (*string)
914 g_free (*string);
915 *string = NULL;
916 if (value)
917 *string = g_strdup (value);
920 gboolean
921 move_file_if_not_same (gchar* src, gchar* dest)
923 gboolean same;
925 g_return_val_if_fail (src != NULL, FALSE);
926 g_return_val_if_fail (dest != NULL, FALSE);
928 if (anjuta_is_installed ("cmp", FALSE) == TRUE)
930 pid_t pid;
931 gint status;
932 if ((pid=fork())==0)
934 execlp ("cmp", "cmp", "-s", src, dest, NULL);
935 g_error ("Cannot execute cmp");
937 waitpid (pid, &status, 0);
938 if (WEXITSTATUS(status)==0)
939 same = TRUE;
940 else
941 same = FALSE;
943 else
945 same = FALSE;
947 /* rename () can't work with 2 different filesystems, so we need
948 to use the couple {copy, remove}. Meanwhile, the files to copy
949 are supposed to be small, so it would spend more time to try
950 rename () to know if a copy/deletion is needed */
952 if (!same && !copy_file (src, dest, FALSE))
953 return FALSE;
955 remove (src);
956 return TRUE;
959 gboolean is_file_same(gchar *a, gchar *b)
961 struct stat st_a,st_b;
963 if(stat(a, &st_a) == -1)
965 /* printf("WARNING: Unable to stat '%s'.", a);*/
966 return FALSE;
968 if(stat(b, &st_b) == -1)
970 /* printf("WARNING: Unable to stat '%s'.", b);*/
971 return FALSE;
974 if(st_a.st_ino == st_b.st_ino)
975 return TRUE;
976 else
977 return FALSE;
980 gchar*
981 get_file_as_buffer (gchar* filename)
983 struct stat s;
984 gchar *buff;
985 gint ret;
986 FILE* fp;
988 g_return_val_if_fail ( filename != NULL, NULL);
989 ret = stat (filename, &s);
990 if (ret != 0)
991 return NULL;
992 fp = fopen(filename, "r");
993 if (!fp)
994 return NULL;
995 buff = g_malloc (s.st_size+3);
996 ret = fread (buff, 1, s.st_size, fp);
997 fclose (fp);
998 buff[ret] = '\0';
999 /* Error is not checked whether all the file is read or not. */
1000 /* Can be checked with ferror() on return from this function */
1001 return buff;
1004 GList*
1005 scan_files_in_dir (const char *dir, int (*select)(const struct dirent *))
1007 struct dirent **namelist;
1008 GList *files = NULL;
1009 int n;
1011 g_return_val_if_fail (dir != NULL, NULL);
1012 if (0 > (n = scandir (dir, &namelist, select, alphasort)))
1013 return NULL;
1014 else
1016 while (n--)
1018 files = g_list_append (files, g_strdup (namelist[n]->d_name));
1019 free(namelist[n]);
1021 free(namelist);
1023 return files;
1026 gchar*
1027 string_from_glist (GList* list)
1029 GList* node;
1030 gchar* str;
1031 if (!list) return NULL;
1033 str = g_strdup("");
1034 node = list;
1035 while (node)
1037 if (node->data)
1039 gchar* tmp;
1040 tmp = str;
1041 str = g_strconcat (tmp, node->data, " ", NULL);
1042 g_free (tmp);
1044 node = g_list_next (node);
1046 if (strlen(str) == 0)
1048 g_free (str);
1049 return NULL;
1051 return str;
1054 select_only_file (const struct dirent *e)
1056 return file_is_regular (e->d_name);
1059 /* Create a new hbox with an image and a label packed into it
1060 * and return the box. */
1061 GtkWidget*
1062 create_xpm_label_box(GtkWidget *parent,
1063 const gchar *xpm_filename, gboolean gnome_pixmap,
1064 const gchar *label_text )
1066 GtkWidget *box1;
1067 GtkWidget *label;
1068 GtkWidget *pixmap;
1070 /* Create box for xpm and label */
1071 box1 = gtk_hbox_new (FALSE, 0);
1073 /* Now on to the xpm stuff */
1074 pixmap = anjuta_res_get_image (xpm_filename);
1076 /* Create a label for the button */
1077 label = gtk_label_new (label_text);
1079 /* Pack the pixmap and label into the box */
1080 gtk_box_pack_start (GTK_BOX (box1),
1081 pixmap, FALSE, FALSE, 0);
1083 gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 3);
1085 gtk_widget_show(pixmap);
1086 gtk_widget_show(label);
1088 return(box1);
1091 /* Excluding the final 0 */
1092 gint calc_string_len( const gchar *szStr )
1094 if( NULL == szStr )
1095 return 0;
1096 return strlen( szStr )*3 ; /* Leave space for the translated character */
1099 gint calc_gnum_len(void)
1101 return 24 ; /* size of a stringfied integer */
1103 /* Allocates a struct of pointers */
1104 gchar **string_parse_separator( const gint nItems, gchar *szStrIn, const gchar chSep )
1106 gchar **szAllocPtrs = (char**)g_new( gchar*, nItems );
1107 if( NULL != szAllocPtrs )
1109 int i ;
1110 gboolean bOK = TRUE ;
1111 gchar *p = szStrIn ;
1112 for( i = 0 ; i < nItems ; i ++ )
1114 gchar *szp ;
1115 szp = strchr( p, chSep ) ;
1116 if( NULL != szp )
1118 szAllocPtrs[i] = p ;
1119 szp[0] = '\0' ; /* Parse Operation */
1120 p = szp + 1 ;
1121 } else
1123 bOK = FALSE ;
1124 break;
1127 if( ! bOK )
1129 g_free( szAllocPtrs );
1130 szAllocPtrs = NULL ;
1133 return szAllocPtrs ;
1137 /* Write in file....*/
1138 gchar *WriteBufUL( gchar* szDst, const gulong ulVal)
1140 return szDst += sprintf( szDst, "%lu,", ulVal );
1143 gchar *WriteBufI( gchar* szDst, const gint iVal )
1145 return szDst += sprintf( szDst, "%d,", iVal );
1148 gchar *WriteBufB( gchar* szDst, const gboolean bVal )
1150 return szDst += sprintf( szDst, "%d,", (int)bVal );
1154 gchar *WriteBufS( gchar* szDst, const gchar* szVal )
1156 if( NULL == szVal )
1158 return szDst += sprintf( szDst, "," );
1159 } else
1161 /* Scrive il valore convertendo eventuali caratteri non alfanumerici */
1162 /*int nLen = strlen( szVal );*/
1163 const gchar *szSrc = szVal ;
1164 while( szSrc[0] )
1166 if( isalnum( szSrc[0] ) || ('.'==szSrc[0]) || ('/'==szSrc[0]) || ('_'==szSrc[0]) )
1168 *szDst++ = *szSrc ;
1169 } else if( '\\' == szSrc[0] )
1171 *szDst++ = *szSrc ;
1172 *szDst++ = *szSrc ;
1173 } else
1175 szDst += sprintf( szDst, "\\%2.2X", (0x00FF&szSrc[0]) );
1177 szSrc++ ;
1179 *szDst++ = ',' ;
1180 *szDst = '\0' ; }
1181 return szDst ;
1184 #define SRCH_CHAR '\\'
1186 static int GetHexAs( const gchar c )
1188 if( isdigit( c ) )
1189 return c - '0' ;
1190 else
1191 return toupper(c) - 'A' + 10 ;
1194 static gchar GetHexb( const gchar c1, const gchar c2 )
1195 { return GetHexAs( c1 ) * 16 + GetHexAs( c2 ) ;
1198 gchar* GetStrCod( const gchar *szIn )
1200 gchar *szRet ;
1201 g_return_val_if_fail( NULL != szIn, NULL );
1202 szRet = g_malloc( strlen( szIn )+2 );
1203 if( NULL != szRet )
1205 gchar* szDst = szRet ;
1206 while( szIn[0] )
1208 if( SRCH_CHAR == szIn[0] )
1210 if( SRCH_CHAR == szIn[1] )
1212 *szDst++ = *szIn ++ ;
1213 szIn ++ ;
1214 } else
1216 *szDst ++ = GetHexb( szIn[1], szIn[2] ) ;
1217 szIn += 3;
1219 } else
1221 *szDst++ = *szIn ++ ;
1224 szDst [0] = '\0' ;
1226 return szRet ;
1229 gchar *get_relative_file_name(gchar *dir, gchar *file)
1231 gchar *real_dir = tm_get_real_path(dir);
1232 gchar *real_file = tm_get_real_path(file);
1233 gchar *retval = NULL;
1235 if (real_dir && real_file)
1237 guint dir_len = strlen(real_dir);
1238 if (0 == strncmp(real_file, real_dir, dir_len))
1239 retval = g_strdup(real_file + dir_len + 1);
1241 g_free(real_dir);
1242 g_free(real_file);
1243 return retval;
1246 gboolean is_file_in_dir(const gchar *file, const gchar *dir)
1248 gboolean status = FALSE;
1250 gchar *real_file_name = tm_get_real_path(file);
1251 gchar *real_dir_name = tm_get_real_path(dir);
1252 if (real_file_name && real_dir_name &&
1253 (0 == strncmp(real_file_name, real_dir_name, strlen(real_dir_name))))
1254 status = TRUE;
1255 g_free(real_file_name);
1256 g_free(real_dir_name);
1257 return status;
1260 gint
1261 anjuta_util_kill (pid_t process_id, const gchar* signal)
1263 int status;
1264 gchar *cmd;
1265 pid_t pid;
1267 cmd = g_strdup_printf ("kill -s %s %d", signal, process_id);
1268 pid = gnome_execute_shell (getenv("HOME"), cmd);
1269 g_free (cmd);
1270 if (pid > 0) {
1271 waitpid (pid, &status, 0);
1272 return 0;
1273 } else {
1274 return -1;
1278 GList*
1279 anjuta_util_parse_args_from_string (const gchar* string)
1281 gboolean escaped;
1282 gchar quote;
1283 gchar buffer[2048];
1284 const gchar *s;
1285 gint idx;
1286 GList* args = NULL;
1288 idx = 0;
1289 escaped = FALSE;
1290 quote = (gchar)-1;
1291 s = string;
1293 while (*s) {
1294 if (!isspace(*s))
1295 break;
1296 s++;
1299 while (*s) {
1300 if (escaped) {
1301 /* The current char was escaped */
1302 buffer[idx++] = *s;
1303 escaped = FALSE;
1304 } else if (*s == '\\') {
1305 /* Current char is an escape */
1306 escaped = TRUE;
1307 } else if (*s == quote) {
1308 /* Current char ends a quotation */
1309 quote = (gchar)-1;
1310 if (!isspace(*(s+1)) && (*(s+1) != '\0')) {
1311 /* If there is no space after the quotation or it is not
1312 the end of the string */
1313 g_warning ("Parse error while parsing program arguments");
1315 } else if ((*s == '\"' || *s == '\'')) {
1316 if (quote == (gchar)-1) {
1317 /* Current char starts a quotation */
1318 quote = *s;
1319 } else {
1320 /* Just a quote char inside quote */
1321 buffer[idx++] = *s;
1323 } else if (quote > 0){
1324 /* Any other char inside quote */
1325 buffer[idx++] = *s;
1326 } else if (isspace(*s)) {
1327 /* Any white space outside quote */
1328 if (idx > 0) {
1329 buffer[idx++] = '\0';
1330 args = g_list_append (args, g_strdup (buffer));
1331 idx = 0;
1333 } else {
1334 buffer[idx++] = *s;
1336 s++;
1338 if (idx > 0) {
1339 /* There are chars in the buffer. Flush as the last arg */
1340 buffer[idx++] = '\0';
1341 args = g_list_append (args, g_strdup (buffer));
1342 idx = 0;
1344 if (quote > 0) {
1345 g_warning ("Unclosed quotation encountered at the end of parsing");
1347 return args;
1350 /* Check which gnome-terminal is installed
1351 Returns: 0 -- No gnome-terminal
1352 Returns: 1 -- Gnome1 gnome-terminal
1353 Returns: 2 -- Gnome2 gnome-terminal */
1355 gint
1356 anjuta_util_check_gnome_terminal (void)
1358 #ifdef DEBUG
1359 gchar* term_command = "gnome-terminal --version";
1360 gchar* term_command2 = "gnome-terminal --disable-factory --version";
1361 #else
1362 gchar* term_command = "gnome-terminal --version > /dev/null 2> /dev/null";
1363 gchar* term_command2 = "gnome-terminal --disable-factory --version > /dev/null 2> /dev/null";
1364 #endif
1365 gint retval;
1367 retval = system (term_command);
1369 /* Command failed or gnome-terminal not found */
1370 if (WEXITSTATUS(retval) != 0)
1371 return 0;
1373 /* gnome-terminal found: Determine version 1 or 2 */
1374 retval = system (term_command2);
1376 /* Command failed or gnome-terminal-2 not found */
1377 if (WEXITSTATUS(retval) != 0)
1378 return 1;
1380 /* gnome-terminal-2 found */
1381 return 2;
1384 static gint
1385 int_from_hex_digit (const gchar ch)
1387 if (isdigit (ch))
1388 return ch - '0';
1389 else if (ch >= 'A' && ch <= 'F')
1390 return ch - 'A' + 10;
1391 else if (ch >= 'a' && ch <= 'f')
1392 return ch - 'a' + 10;
1393 else
1394 return 0;
1397 void
1398 anjuta_util_color_from_string (const gchar * val, guint8 * r, guint8 * g, guint8 * b)
1400 *r = int_from_hex_digit (val[1]) * 16 + int_from_hex_digit (val[2]);
1401 *g = int_from_hex_digit (val[3]) * 16 + int_from_hex_digit (val[4]);
1402 *b = int_from_hex_digit (val[5]) * 16 + int_from_hex_digit (val[6]);
1405 gchar *
1406 anjuta_util_string_from_color (guint8 r, guint8 g, guint8 b)
1408 gchar str[10];
1409 guint32 num;
1411 num = r;
1412 num <<= 8;
1413 num += g;
1414 num <<= 8;
1415 num += b;
1417 sprintf (str, "#%06X", num);
1418 return g_strdup (str);
1421 gchar *
1422 anjuta_util_convert_to_utf8 (const gchar *str)
1424 GError *error = NULL;
1425 gchar *utf8_msg_string = NULL;
1427 g_return_val_if_fail (str != NULL, NULL);
1428 g_return_val_if_fail (strlen (str) > 0, NULL);
1430 if (g_utf8_validate(str, -1, NULL))
1432 utf8_msg_string = g_strdup (str);
1434 else
1436 gsize rbytes, wbytes;
1437 utf8_msg_string = g_locale_to_utf8 (str, -1, &rbytes, &wbytes, &error);
1438 if (error != NULL) {
1439 g_warning ("g_locale_to_utf8 failed: %s\n", error->message);
1440 g_error_free (error);
1441 g_free (utf8_msg_string);
1442 return NULL;
1445 return utf8_msg_string;
1448 GtkWidget *
1449 anjuta_util_toolbar_append_button (GtkWidget *toolbar, const gchar *iconfile,
1450 const gchar *label, const gchar *tooltip,
1451 GtkSignalFunc callback, gpointer user_data)
1453 GtkWidget *icon = anjuta_res_get_image (iconfile);
1454 GtkWidget *item =
1455 gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
1456 GTK_TOOLBAR_CHILD_BUTTON, NULL,
1457 label, tooltip, NULL,
1458 icon, callback, user_data);
1459 gtk_widget_ref (item);
1460 gtk_widget_show (item);
1461 return item;
1464 GtkWidget *
1465 anjuta_util_toolbar_append_stock (GtkWidget *toolbar, const gchar *stock_icon,
1466 const gchar *tooltip, GtkSignalFunc callback,
1467 gpointer user_data)
1469 GtkWidget *item;
1470 item =
1471 gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
1472 stock_icon,
1473 tooltip, NULL,
1474 callback, user_data, -1);
1475 gtk_widget_ref (item);
1476 gtk_widget_show (item);
1477 return item;
1480 GtkWidget*
1481 anjuta_button_new_with_stock_image (const gchar* text, const gchar* stock_id)
1483 GtkWidget *button;
1484 GtkStockItem item;
1485 GtkWidget *label;
1486 GtkWidget *image;
1487 GtkWidget *hbox;
1488 GtkWidget *align;
1490 button = gtk_button_new ();
1492 if (GTK_BIN (button)->child)
1493 gtk_container_remove (GTK_CONTAINER (button),
1494 GTK_BIN (button)->child);
1496 if (gtk_stock_lookup (stock_id, &item))
1498 label = gtk_label_new_with_mnemonic (text);
1500 gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (button));
1502 image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
1503 hbox = gtk_hbox_new (FALSE, 2);
1505 align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
1507 gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
1508 gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1510 gtk_container_add (GTK_CONTAINER (button), align);
1511 gtk_container_add (GTK_CONTAINER (align), hbox);
1512 gtk_widget_show_all (align);
1514 return button;
1517 label = gtk_label_new_with_mnemonic (text);
1518 gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (button));
1520 gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
1522 gtk_widget_show (label);
1523 gtk_container_add (GTK_CONTAINER (button), label);
1525 return button;
1528 GtkWidget*
1529 anjuta_dialog_add_button (GtkDialog *dialog, const gchar* text,
1530 const gchar* stock_id, gint response_id)
1532 GtkWidget *button;
1534 g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
1535 g_return_val_if_fail (text != NULL, NULL);
1536 g_return_val_if_fail (stock_id != NULL, NULL);
1538 button = anjuta_button_new_with_stock_image (text, stock_id);
1539 g_return_val_if_fail (button != NULL, NULL);
1541 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1543 gtk_widget_show (button);
1545 gtk_dialog_add_action_widget (dialog, button, response_id);
1547 return button;